Compare commits

..

42 Commits

Author SHA1 Message Date
dbaa7c5113 Merge pull request #310 from ONLYOFFICE/bugfix/file-request-status
Bugfix/file request status
2022-11-21 13:25:47 +03:00
d6ad145111 nodejs: init type argument (fix ab03bb5490) 2022-11-18 13:51:11 +03:00
44fb3a089c php: added request timeout for download 2022-11-11 14:58:36 +03:00
513bf99adb csharp-mvc: added request timeout for download 2022-11-11 12:23:39 +03:00
6f92633ef8 csharp: added request timeout for download 2022-11-11 12:23:28 +03:00
b67e768dce python: added request status check for file 2022-11-10 19:07:17 +03:00
751a886bfa ruby: added request status check for file 2022-11-10 19:06:29 +03:00
66ea4b144b java: added request status check for file 2022-11-10 19:05:32 +03:00
7a73422231 java-spring: added request status check for file 2022-11-10 19:04:49 +03:00
93accdac7c nodejs: do not send key in referenceData 2022-11-08 16:33:19 +03:00
def268f5f2 Merge remote-tracking branch 'remotes/origin/release/1.4.0' into develop 2022-11-08 10:42:00 +03:00
a7c917db3f Merge remote-tracking branch 'remotes/origin/release/1.4.0' into develop 2022-11-08 09:18:02 +03:00
82efd0f18a fix 848cfb20bc 2022-11-07 14:23:01 +03:00
8ce90d89ed removed enum Language (Fix Bug 59624) 2022-11-07 13:07:34 +03:00
9277d3de58 Merge branch 'feature/optionDirectUrl' into develop 2022-11-03 13:34:47 +03:00
baf7a1e5dd fix changelog about directUrl task 2022-11-03 13:34:15 +03:00
e2a14a74db Merge pull request #308 from ONLYOFFICE/feature/optionDirectUrl
Feature/option direct url
2022-11-03 13:33:20 +03:00
848cfb20bc set language from cookies (Fix Bug 59352) 2022-11-03 12:05:53 +03:00
ddd3ec82a8 update pyjwt=2.6.0 (Fix Bug 59369) 2022-11-03 10:47:39 +03:00
0ed08fd7b2 Change CHANGELOG.md 2022-11-02 14:58:12 +03:00
e1c5907003 csharp: option to send directUrl 2022-11-02 14:54:33 +03:00
9dd2d7c0db csharp-mvc: fix label for aspx 2022-11-02 14:49:40 +03:00
8f0cbb78af Change CHANGELOG.md 2022-11-02 13:10:39 +03:00
72e48914aa Merge branch 'feature/optionDirectUrl' of https://github.com/ONLYOFFICE/document-server-integration into feature/optionDirectUrl 2022-11-02 13:05:45 +03:00
82a282029a csharp-mvc: option to send directUrl 2022-11-02 13:05:08 +03:00
9b7c12b5c0 Change CHANGELOG.md 2022-11-01 23:10:46 +03:00
6ea5546099 python: option to send directUrl 2022-11-01 23:09:36 +03:00
92fbd1e293 Change CHANGELOG.md 2022-10-28 16:48:05 +03:00
855c1ed9f9 php: option to send directUrl 2022-10-28 16:47:08 +03:00
7e60ec15fd Change CHANGELOG.md 2022-10-28 13:56:28 +03:00
3697a4a888 ruby: option to send directUrl 2022-10-28 13:55:48 +03:00
0b8107d167 Change CHANGELOG.md 2022-10-28 13:52:11 +03:00
885850ee33 java: option to send directUrl 2022-10-27 14:32:21 +03:00
98c61250a6 Change CHANGELOG.md 2022-10-26 16:54:16 +03:00
457487844c java-spring: fix option to send directUrl 2022-10-26 16:47:43 +03:00
ff72956b68 java-spring: option to send directUrl 2022-10-26 16:41:59 +03:00
cda8a86c2a Merge remote-tracking branch 'remotes/origin/release/1.4.0' into develop 2022-10-26 13:40:30 +03:00
e96200df85 java-spring: tooltip fix 2022-10-26 11:53:50 +03:00
de75b11e18 java-spring: option to send directUrl 2022-10-26 11:48:11 +03:00
f27afe1535 java-spring: option to send directUrl 2022-10-25 19:44:39 +03:00
1bdb3c03bc Merge remote-tracking branch 'remotes/origin/feature/referenceData' into develop 2022-10-14 10:22:24 +03:00
111dc14f2b nodejs: referenceData 2022-10-14 10:20:45 +03:00
56 changed files with 738 additions and 198 deletions

View File

@ -1,5 +1,8 @@
# Change Log
- nodejs: referenceData
- option to send directUrl
## 1.4.0
- nodejs: option to send directUrl
- opening file on client by directUrl
@ -34,6 +37,5 @@
- creating docxf
- opening docxf, oform
## 1.0.0
- added java spring

View File

@ -167,7 +167,7 @@ label .checkbox {
background-image: url("images/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}

View File

@ -16,6 +16,7 @@
*
*/
using System;
using System.IO;
using System.Web.Mvc;
using OnlineEditorsExampleMVC.Helpers;
@ -31,13 +32,14 @@ namespace OnlineEditorsExampleMVC.Controllers
}
// viewing file in the editor
public ActionResult Editor(string fileName, string editorsMode, string editorsType)
public ActionResult Editor(string fileName, string editorsMode, string editorsType, string directUrl)
{
var file = new FileModel
{
Mode = editorsMode, // editor mode: edit or view
Type = editorsType, // editor type: desktop, mobile, embedded
FileName = Path.GetFileName(fileName) // file name
FileName = Path.GetFileName(fileName), // file name
IsEnabledDirectUrl = directUrl != null ? Convert.ToBoolean(directUrl) : false
};
return View("Editor", file);

View File

@ -442,5 +442,11 @@ namespace OnlineEditorsExampleMVC.Helpers
}
return languages;
}
public static string GetDirectUrl()
{
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
return isEnabledDirectUrl != null ? isEnabledDirectUrl : "false";
}
}
}

View File

@ -321,6 +321,7 @@ namespace OnlineEditorsExampleMVC.Helpers
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
var req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 5000;
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
{
if (stream == null) throw new Exception("stream is null");

View File

@ -33,6 +33,7 @@ namespace OnlineEditorsExampleMVC.Models
{
public string Mode { get; set; } // editor mode
public string Type { get; set; } // editor type
public bool IsEnabledDirectUrl { get; set; } // is enabled direct url
// get file url for Document Server
public string FileUri
@ -126,7 +127,7 @@ namespace OnlineEditorsExampleMVC.Models
{
{ "title", FileName },
{ "url", DownloadUrl },
{ "directUrl", directUrl },
{ "directUrl", IsEnabledDirectUrl ? directUrl : "" },
{ "fileType", ext.Trim('.') },
{ "key", Key },
{
@ -286,7 +287,10 @@ namespace OnlineEditorsExampleMVC.Models
}
dataObj.Add("url", prevFileUrl);
dataObj.Add("directUrl", directPrevFileUrl);
if (IsEnabledDirectUrl)
{
dataObj.Add("directUrl", directPrevFileUrl);
}
dataObj.Add("version", i);
if (i > 1) // check if the version number is greater than 1 (the file was modified)
{
@ -304,11 +308,15 @@ namespace OnlineEditorsExampleMVC.Models
obj.Add("user", change.Count > 0 ? change["user"] : null);
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
dataObj.Add("previous", IsEnabledDirectUrl ? new Dictionary<string, object>() { // write information about previous file version to the data object with direct url
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
{ "directUrl", prev["directUrl"] },
} : new Dictionary<string, object>() { // write information about previous file version to the data object without direct url
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
});
// write the path to the diff.zip archive with differences in this file version
var changesUrl = DocManagerHelper.GetHistoryDownloadUrl(FileName, (i - 1).ToString(), "diff.zip");
@ -359,10 +367,14 @@ namespace OnlineEditorsExampleMVC.Models
var dataCompareFile = new Dictionary<string, object>
{
{ "fileType", "docx" },
{ "url", compareFileUrl.ToString() },
{ "directUrl", directCompareFileUrl.ToString()}
{ "url", compareFileUrl.ToString() }
};
if (IsEnabledDirectUrl)
{
dataCompareFile.Add("directUrl", directCompareFileUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var compareFileToken = JwtManager.Encode(dataCompareFile); // encode the dataCompareFile object into the token
@ -396,10 +408,14 @@ namespace OnlineEditorsExampleMVC.Models
var logoConfig = new Dictionary<string, object>
{
{ "fileType", "png"},
{ "url", mailMergeUrl.ToString()},
{ "directUrl", directMailMergeUrl.ToString()}
{ "url", mailMergeUrl.ToString()}
};
if (IsEnabledDirectUrl)
{
logoConfig.Add("directUrl", directMailMergeUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var token = JwtManager.Encode(logoConfig); // encode logoConfig into the token
@ -437,10 +453,14 @@ namespace OnlineEditorsExampleMVC.Models
var mailMergeConfig = new Dictionary<string, object>
{
{ "fileType", "csv" },
{ "url", mailMergeUrl.ToString()},
{ "directUrl", directMailMergeUrl.ToString()}
{ "url", mailMergeUrl.ToString()}
};
if (IsEnabledDirectUrl)
{
mailMergeConfig.Add("directUrl", directMailMergeUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var mailmergeToken = JwtManager.Encode(mailMergeConfig); // encode mailMergeConfig into the token

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery != "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function () {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq('#fileupload').fileupload({
dataType: 'json',
@ -219,7 +232,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?fileName=" + fileId;
var url = UrlEditor + "?fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -227,7 +240,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId;
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -235,7 +248,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId;
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -289,6 +302,17 @@ if (typeof jQuery != "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
var fileList = jq("tr.tableRow");
var mouseIsOverTooltip = false;
@ -304,7 +328,7 @@ if (typeof jQuery != "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);

View File

@ -70,7 +70,7 @@
<a class="try-editor form" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input id="createSample" class="checkbox" type="checkbox" />With sample content
</label>
</div>
@ -86,7 +86,7 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" src="content/images/info.svg" />
<img id="info" src="content/images/info.svg" />
<select class="select-user" id="user">
<% foreach (User user in Users.getAllUsers())
{ %>
@ -107,6 +107,14 @@
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="content/images/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
@ -156,7 +164,8 @@
<tbody>
<% foreach (var storedFile in storedFiles)
{
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var isEnabledDirectUrl = DocManagerHelper.GetDirectUrl();
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var docType = FileUtility.GetFileType(storedFile.Name).ToString().ToLower();
var ext = Path.GetExtension(storedFile.Name).ToLower();
var canEdit = DocManagerHelper.EditedExts.Contains(ext);
@ -165,42 +174,42 @@
<tr class="tableRow" title="<%= storedFile.Name %> [<%= DocManagerHelper.GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress.Replace(':', '_')) %>]">
<td class="contentCells">
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name }) %>" target="_blank">
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, directUrl = isEnabledDirectUrl }) %>" target="_blank">
<span><%= storedFile.Name %></span>
</a>
</td>
<% if (canEdit) { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
<% } else if (docType == "cell") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
</a>
</td>
<% } %>
<% if (docType == "word") { %>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
@ -212,7 +221,7 @@
<% } %>
<% if (isFillFormDoc) { %>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -222,7 +231,7 @@
<% } else if (isFillFormDoc) { %>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices"/>
</a>
</td>
@ -230,7 +239,7 @@
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -238,17 +247,17 @@
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
<% } %>
<td class="contentCells contentCells-icon firstContentCellViewers">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded" }) %>" target="_blank">
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded", directUrl = isEnabledDirectUrl }) %>" target="_blank">
<img src="content/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>

View File

@ -167,7 +167,7 @@ label .checkbox {
background-image: url("images/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}

View File

@ -73,7 +73,7 @@
<a class="try-editor form" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input id="createSample" class="checkbox" type="checkbox" />With sample content
</label>
</div>
@ -109,6 +109,14 @@
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="app_themes/images/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
@ -158,7 +166,8 @@
<tbody>
<% foreach (var storedFile in storedFiles)
{
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
var directUrlParam = GetDirectUrlParam();
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name) + directUrlParam;
var ext = Path.GetExtension(storedFile.Name).ToLower();
var docType = DocumentType(storedFile.Name);
var canEdit = EditedExts.Contains(ext);

View File

@ -626,5 +626,11 @@ namespace OnlineEditorsExample
}
return languages;
}
public static string GetDirectUrlParam()
{
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
return "&directUrl=" + (isEnabledDirectUrl != null ? isEnabledDirectUrl : "false");
}
}
}

View File

@ -195,7 +195,7 @@ namespace OnlineEditorsExample
{
{ "title", FileName },
{ "url", getDownloadUrl(FileName) },
{ "directUrl", directUrl },
{ "directUrl", IsEnabledDirectUrl() ? directUrl : "" },
{ "fileType", ext.Trim('.') },
{ "key", Key },
{
@ -377,7 +377,12 @@ namespace OnlineEditorsExample
}
dataObj.Add("url", prevFileUrl); // write file url to the data object
dataObj.Add("directUrl", directPrevFileUrl); // write direct url to the data object
if (IsEnabledDirectUrl())
{
dataObj.Add("directUrl", directPrevFileUrl); // write direct url to the data object
}
dataObj.Add("version", i);
if (i > 1) // check if the version number is greater than 1 (the file was modified)
{
@ -395,12 +400,19 @@ namespace OnlineEditorsExample
obj.Add("user", change.Count > 0 ? change["user"] : null);
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
Dictionary<string, object> dataPrev = new Dictionary<string, object>() { // write information about previous file version to the data object
{ "fileType", prev["fileType"] },
{ "key", prev["key"] }, // write key and url information about previous file version
{ "url", prev["url"] },
{ "directUrl", prev["directUrl"] },
});
{ "url", prev["url"] }
};
if (IsEnabledDirectUrl())
{
dataPrev.Add("directUrl", prev["directUrl"]);
}
dataObj.Add("previous", dataPrev);
// write the path to the diff.zip archive with differences in this file version
var changesUrl = MakePublicHistoryUrl(FileName, (i - 1).ToString(), "diff.zip");
dataObj.Add("changesUrl", changesUrl);
@ -442,10 +454,14 @@ namespace OnlineEditorsExample
Dictionary<string, object> logoConfig = new Dictionary<string, object>
{
{ "fileType", "png"},
{ "url", InsertImageUrl.ToString()},
{ "directUrl", DirectImageUrl.ToString()}
{ "url", InsertImageUrl.ToString()}
};
if (IsEnabledDirectUrl())
{
logoConfig.Add("directUrl", DirectImageUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var insImageToken = JwtManager.Encode(logoConfig); // encode logoConfig into the token
@ -475,10 +491,14 @@ namespace OnlineEditorsExample
Dictionary<string, object> dataCompareFile = new Dictionary<string, object>
{
{ "fileType", "docx" },
{ "url", compareFileUrl.ToString() },
{ "directUrl", DirectFileUrl.ToString() }
{ "url", compareFileUrl.ToString() }
};
if (IsEnabledDirectUrl())
{
dataCompareFile.Add("directUrl", DirectFileUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var compareFileToken = JwtManager.Encode(dataCompareFile); // encode the dataCompareFile object into the token
@ -510,10 +530,14 @@ namespace OnlineEditorsExample
Dictionary<string, object> mailMergeConfig = new Dictionary<string, object>
{
{ "fileType", "csv" },
{ "url", mailmergeUrl.ToString() },
{ "directUrl", DirectMailMergeUrl.ToString() }
{ "url", mailmergeUrl.ToString() }
};
if (IsEnabledDirectUrl())
{
mailMergeConfig.Add("directUrl", DirectMailMergeUrl.ToString());
}
if (JwtManager.Enabled) // if the secret key to generate token exists
{
var mailmergeToken = JwtManager.Encode(mailMergeConfig); // encode mailMergeConfig into the token
@ -615,5 +639,12 @@ namespace OnlineEditorsExample
{ "name", uname }
}));
}
// get direct url flag
private static bool IsEnabledDirectUrl()
{
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
return isEnabledDirectUrl != null ? Convert.ToBoolean(isEnabledDirectUrl) : false;
}
}
}

View File

@ -324,6 +324,7 @@ namespace OnlineEditorsExample
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
var req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 5000;
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
{
if (stream == null) throw new Exception("stream is null");

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery != "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function () {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq('#fileupload').fileupload({
dataType: 'json',
@ -219,7 +232,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.aspx?fileID=" + fileId;
var url = "doceditor.aspx?fileID=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -227,7 +240,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.aspx?editorsMode=view&fileID=" + fileId;
var url = "doceditor.aspx?editorsMode=view&fileID=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -235,7 +248,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.aspx?editorsType=embedded&editorsMode=embedded&fileID=" + fileId;
var url = "doceditor.aspx?editorsType=embedded&editorsMode=embedded&fileID=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -288,6 +301,17 @@ if (typeof jQuery != "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
var fileList = jq("tr.tableRow");
var mouseIsOverTooltip = false;
@ -303,7 +327,7 @@ if (typeof jQuery != "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);

View File

@ -79,6 +79,7 @@ public class EditorController {
@RequestParam(value = "action", required = false) String actionParam,
@RequestParam(value = "type", required = false) String typeParam,
@RequestParam(value = "actionLink", required = false) String actionLink,
@RequestParam(value = "directUrl", required = false, defaultValue = "false") Boolean directUrl,
@CookieValue(value = "uid") String uid,
@CookieValue(value = "ulang") String lang,
Model model) throws JsonProcessingException {
@ -115,6 +116,7 @@ public class EditorController {
.action(action)
.user(user)
.actionData(actionLink)
.isEnableDirectUrl(directUrl)
.build()
);
@ -122,9 +124,9 @@ public class EditorController {
model.addAttribute("model", fileModel); // add file model with the default parameters to the original model
model.addAttribute("fileHistory", historyManager.getHistory(fileModel.getDocument())); // get file history and add it to the model
model.addAttribute("docserviceApiUrl",docserviceSite + docserviceApiUrl); // create the document service api URL and add it to the model
model.addAttribute("dataInsertImage", getInsertImage()); // get an image and add it to the model
model.addAttribute("dataCompareFile", getCompareFile()); // get a document for comparison and add it to the model
model.addAttribute("dataMailMergeRecipients", getMailMerge()); // get recipients data for mail merging and add it to the model
model.addAttribute("dataInsertImage", getInsertImage(directUrl)); // get an image and add it to the model
model.addAttribute("dataCompareFile", getCompareFile(directUrl)); // get a document for comparison and add it to the model
model.addAttribute("dataMailMergeRecipients", getMailMerge(directUrl)); // get recipients data for mail merging and add it to the model
model.addAttribute("usersForMentions", getUserMentions(uid)); // get user data for mentions and add it to the model
return "editor.html";
}
@ -144,11 +146,13 @@ public class EditorController {
}
@SneakyThrows
private String getInsertImage() { // get an image that will be inserted into the document
private String getInsertImage(Boolean directUrl) { // get an image that will be inserted into the document
Map<String, Object> dataInsertImage = new HashMap<>();
dataInsertImage.put("fileType", "png");
dataInsertImage.put("url", storagePathBuilder.getServerUrl(true) + "/css/img/logo.png");
dataInsertImage.put("directUrl", storagePathBuilder.getServerUrl(false) + "/css/img/logo.png");
if (directUrl) {
dataInsertImage.put("directUrl", storagePathBuilder.getServerUrl(false) + "/css/img/logo.png");
}
// check if the document token is enabled
if(jwtManager.tokenEnabled()){
@ -159,11 +163,13 @@ public class EditorController {
}
@SneakyThrows
private String getCompareFile(){ // get a document that will be compared with the current document
private String getCompareFile(Boolean directUrl) { // get a document that will be compared with the current document
Map<String, Object> dataCompareFile = new HashMap<>();
dataCompareFile.put("fileType", "docx");
dataCompareFile.put("url", storagePathBuilder.getServerUrl(true) + "/assets?name=sample.docx");
dataCompareFile.put("directUrl", storagePathBuilder.getServerUrl(false) + "/assets?name=sample.docx");
if (directUrl) {
dataCompareFile.put("directUrl", storagePathBuilder.getServerUrl(false) + "/assets?name=sample.docx");
}
// check if the document token is enabled
if(jwtManager.tokenEnabled()){
@ -174,11 +180,13 @@ public class EditorController {
}
@SneakyThrows
private String getMailMerge(){
private String getMailMerge(Boolean directUrl) {
Map<String, Object> dataMailMergeRecipients = new HashMap<>(); // get recipients data for mail merging
dataMailMergeRecipients.put("fileType", "csv");
dataMailMergeRecipients.put("url", storagePathBuilder.getServerUrl(true) + "/csv");
dataMailMergeRecipients.put("directUrl", storagePathBuilder.getServerUrl(false) + "/csv");
if (directUrl) {
dataMailMergeRecipients.put("directUrl", storagePathBuilder.getServerUrl(false) + "/csv");
}
// check if the document token is enabled
if(jwtManager.tokenEnabled()){

View File

@ -68,7 +68,8 @@ public class IndexController {
private String langs;
@GetMapping("${url.index}")
public String index(Model model){
public String index(@RequestParam(value = "directUrl", required = false) Boolean directUrl,
Model model){
java.io.File[] files = storageMutator.getStoredFiles(); // get all the stored files from the storage
List<String> docTypes = new ArrayList<>();
List<Boolean> filesEditable = new ArrayList<>();
@ -107,6 +108,7 @@ public class IndexController {
model.addAttribute("tooltip", tooltip);
model.addAttribute("users", users);
model.addAttribute("languages", languages);
model.addAttribute("directUrl", directUrl);
return "index.html";
}

View File

@ -76,8 +76,15 @@ public class DefaultCallbackManager implements CallbackManager {
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
connection.setConnectTimeout(5000);
InputStream stream = connection.getInputStream(); // get input stream of the file information from the URL
int statusCode = connection.getResponseCode();
if (statusCode != 200) { // checking status code
connection.disconnect();
throw new RuntimeException("Document editing service returned status: " + statusCode);
}
if (stream == null) {
connection.disconnect();
throw new RuntimeException("Input stream is null");

View File

@ -91,8 +91,10 @@ public class DefaultHistoryManager implements HistoryManager {
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.getUrl() :
documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), true));
dataObj.put("directUrl", i == curVer ? document.getDirectUrl() :
documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), false));
if (!document.getDirectUrl().equals("")) {
dataObj.put("directUrl", i == curVer ? document.getDirectUrl() :
documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), false));
}
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
@ -111,7 +113,9 @@ public class DefaultHistoryManager implements HistoryManager {
prevInfo.put("fileType", prev.get("fileType"));
prevInfo.put("key", prev.get("key")); // write key and URL information about previous file version
prevInfo.put("url", prev.get("url"));
prevInfo.put("directUrl", prev.get("directUrl"));
if (!document.getDirectUrl().equals("")) {
prevInfo.put("directUrl", prev.get("directUrl"));
}
dataObj.put("previous", prevInfo); // write information about previous file version to the data object
// write the path to the diff.zip archive with differences in this file version
Integer verdiff = i - 1;

View File

@ -95,6 +95,13 @@ public class DefaultServiceConverter implements ServiceConverter
}
connection.connect();
int statusCode = connection.getResponseCode();
if (statusCode != 200) { // checking status code
connection.disconnect();
throw new RuntimeException("Convertation service returned status: " + statusCode);
}
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte); // write bytes to the output stream
os.flush(); // force write data to the output stream that can be cached in the current thread

View File

@ -55,7 +55,7 @@ public class DefaultDocumentConfigurer implements DocumentConfigurer<DefaultDocu
document.setTitle(fileName); // set the title to the document config
document.setUrl(documentManager.getDownloadUrl(fileName, true)); // set the URL to download a file to the document config
document.setUrlUser(documentManager.getFileUri(fileName, false)); // set the file URL to the document config
document.setDirectUrl(documentManager.getDownloadUrl(fileName, false));
document.setDirectUrl(wrapper.getIsEnableDirectUrl() ? documentManager.getDownloadUrl(fileName, false) : "");
document.setFileType(fileUtility.getFileExtension(fileName).replace(".","")); // set the file type to the document config
document.getInfo().setFavorite(wrapper.getFavorite()); // set the favorite parameter to the document config

View File

@ -80,6 +80,7 @@ public class DefaultFileConfigurer implements FileConfigurer<DefaultFileWrapper>
.fileName(fileName)
.permission(updatePermissions(userPermissions, action, canEdit))
.favorite(wrapper.getUser().getFavorite())
.isEnableDirectUrl(wrapper.getIsEnableDirectUrl())
.build();
defaultDocumentConfigurer.configure(fileModel.getDocument(), documentWrapper); // define the document configurer

View File

@ -28,4 +28,5 @@ public class DefaultDocumentWrapper {
private Permission permission;
private String fileName;
private Boolean favorite;
private Boolean isEnableDirectUrl;
}

View File

@ -36,4 +36,5 @@ public class DefaultFileWrapper {
private Action action;
private String actionData;
private Boolean canEdit;
private Boolean isEnableDirectUrl;
}

View File

@ -167,7 +167,7 @@ label .checkbox {
background-image: url("img/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery !== "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function() {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq("#fileupload").fileupload({
dataType: "json",
@ -228,7 +241,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?action=edit&fileName=" + fileId;
var url = UrlEditor + "?action=edit&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -236,7 +249,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?action=view&fileName=" + fileId;
var url = UrlEditor + "?action=view&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -244,7 +257,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?type=embedded&action=embedded&fileName=" + fileId;
var url = UrlEditor + "?type=embedded&action=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -300,6 +313,17 @@ if (typeof jQuery !== "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
jq("#portal-info")[0].innerHTML += jq("#portal-info")[0].attributes.tooltip.value;
var fileList = jq("tr.tableRow");
@ -317,7 +341,7 @@ if (typeof jQuery !== "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);

View File

@ -59,7 +59,7 @@
<a class="try-editor form" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input id="createSample" class="checkbox" type="checkbox" />With sample content
</label>
</div>
@ -75,7 +75,7 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" src="css/img/info.svg"/>
<img id="info" class="info" src="css/img/info.svg"/>
<select class="select-user" id="user">
<option th:each="user : ${users}"
th:value="${user.id}"
@ -93,6 +93,14 @@
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="css/img/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
@ -129,43 +137,50 @@
<tr th:each="file,iState : ${files}" class="tableRow" th:title="${files[iState.index].getName() + versions[iState.index]}">
<td class="contentCells">
<a class="stored-edit" th:classappend="${docTypes[iState.index]}"
th:href="@{/editor(fileName=${files[iState.index].getName()})}" target="_blank">
th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()}, __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<span th:text="${files[iState.index].getName()}"></span>
</a>
</td>
<th:block th:if="${filesEditable[iState.index]}">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='edit')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='edit', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='edit')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='edit', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'cell'">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
</a>
</td>
</div>
<div th:if="${docTypes[iState.index]} eq 'word'">
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
@ -178,7 +193,8 @@
</div>
<div th:if="${isFillFormDoc[iState.index]}">
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -190,7 +206,8 @@
<th:block th:if="${isFillFormDoc[iState.index] and not filesEditable[iState.index]}">
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices" />
</a>
</td>
@ -198,7 +215,8 @@
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -207,17 +225,20 @@
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
</th:block>
<td class="contentCells contentCells-icon firstContentCellViewers">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='view')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='view', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='view')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='view', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='embedded',action='embedded')}" target="_blank">
<a th:with="directUrl=${directUrl}"
th:href="@{/editor(fileName=${files[iState.index].getName()},type='embedded',action='embedded', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
<img src="css/img/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>

View File

@ -47,6 +47,7 @@ public class EditorServlet extends HttpServlet
String fileName = FileUtility.GetFileName(request.getParameter("fileName"));
String fileExt = request.getParameter("fileExt");
String sample = request.getParameter("sample");
Boolean isEnableDirectUrl = Boolean.valueOf(request.getParameter("directUrl"));
// check if there is sample data in the request
Boolean sampleData = (sample == null || sample.isEmpty()) ? false : sample.toLowerCase().equals("true");
@ -70,7 +71,7 @@ public class EditorServlet extends HttpServlet
}
// create file model (get all the necessary parameters from cookies)
FileModel file = new FileModel(fileName, cm.getCookie("ulang"), request.getParameter("actionLink"), user);
FileModel file = new FileModel(fileName, cm.getCookie("ulang"), request.getParameter("actionLink"), user, isEnableDirectUrl);
// change type parameter if needed
file.changeType(request.getParameter("mode"), request.getParameter("type"), user, fileName);
@ -78,19 +79,25 @@ public class EditorServlet extends HttpServlet
Map<String, Object> dataInsertImage = new HashMap<>();
dataInsertImage.put("fileType", "png");
dataInsertImage.put("url", DocumentManager.GetServerUrl(true) + "/css/img/logo.png");
dataInsertImage.put("directUrl", DocumentManager.GetServerUrl(false) + "/css/img/logo.png");
if (isEnableDirectUrl) {
dataInsertImage.put("directUrl", DocumentManager.GetServerUrl(false) + "/css/img/logo.png");
}
// a document that will be compared with the current document
Map<String, Object> dataCompareFile = new HashMap<>();
dataCompareFile.put("fileType", "docx");
dataCompareFile.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=assets&name=sample.docx");
dataCompareFile.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=assets&name=sample.docx");
if (isEnableDirectUrl) {
dataCompareFile.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=assets&name=sample.docx");
}
// recipients data for mail merging
Map<String, Object> dataMailMergeRecipients = new HashMap<>();
dataMailMergeRecipients.put("fileType", "csv");
dataMailMergeRecipients.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=csv");
dataMailMergeRecipients.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=csv");
if (isEnableDirectUrl) {
dataMailMergeRecipients.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=csv");
}
// users data for mentions
List<Map<String, Object>> usersForMentions = Users.getUsersForMentions(user.id);

View File

@ -40,7 +40,7 @@ public class FileModel
public String token;
// create file model
public FileModel(String fileName, String lang, String actionData, User user)
public FileModel(String fileName, String lang, String actionData, User user, Boolean isEnableDirectUrl)
{
if (fileName == null) fileName = "";
fileName = fileName.trim(); // remove extra spaces in the file name
@ -52,7 +52,7 @@ public class FileModel
document = new Document();
document.title = fileName;
document.url = DocumentManager.GetDownloadUrl(fileName, true); // get file url
document.directUrl = DocumentManager.GetDownloadUrl(fileName, false); // get direct url
document.directUrl = isEnableDirectUrl ? DocumentManager.GetDownloadUrl(fileName, false) : ""; // get direct url
document.fileType = FileUtility.GetFileExtension(fileName).replace(".", ""); // get file extension from the file name
// generate document key
document.key = ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + "/" + fileName + "/" + Long.toString(new File(DocumentManager.StoragePath(fileName, null)).lastModified()));
@ -185,7 +185,9 @@ public class FileModel
dataObj.put("fileType", FileUtility.GetFileExtension(document.title).substring(1));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), true));
dataObj.put("directUrl", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), false));
if (!document.directUrl.equals("")) {
dataObj.put("directUrl", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), false));
}
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1

View File

@ -143,6 +143,12 @@ public class ServiceConverter
}
connection.connect();
int statusCode = connection.getResponseCode();
if (statusCode != 200) { // checking status code
connection.disconnect();
throw new Exception("Conversion service returned status: " + statusCode);
}
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte);
}

View File

@ -253,6 +253,14 @@ public class TrackManager {
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
connection.setConnectTimeout(5000);
int statusCode = connection.getResponseCode();
if (statusCode != 200) { // checking status code
connection.disconnect();
throw new RuntimeException("Document editing service returned status: " + statusCode);
}
InputStream stream = connection.getInputStream(); // get input stream of the file information from the url
if (stream == null)

View File

@ -167,7 +167,7 @@ label .checkbox {
background-image: url("img/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}

View File

@ -87,7 +87,7 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" src="css/img/info.svg" />
<img id="info" src="css/img/info.svg" />
<select class="select-user" id="user">
<% for (User user : Users.getAllUsers()) { %>
<option value="<%= user.id %>"><%= user.name == null ? "Anonymous" : user.name %></option>
@ -106,6 +106,12 @@
</select>
</td>
</tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="css/img/info.svg" />
</label>
</td>
</tbody>
</table>
</div>
@ -159,42 +165,44 @@
%>
<tr class="tableRow" title="<%= files[i].getName() %><%= version %>">
<td class="contentCells">
<a class="stored-edit <%= docType %>" href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>" target="_blank">
<a class="stored-edit <%= docType %>" href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>" target="_blank">
<span><%= files[i].getName() %></span>
</a>
</td>
<% if (canEdit) { %>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=edit" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=edit" target="_blank">
<img src="css/img/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=mobile&mode=edit" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=mobile&mode=edit" target="_blank">
<img src="css/img/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=comment" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=comment" target="_blank">
<img src="css/img/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
<% if (docType.equals("word")) { %>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=review" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=review" target="_blank">
<img src="css/img/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
<% } else if (docType.equals("cell")) { %>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=filter" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=filter" target="_blank">
<img src="css/img/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter"/>
</a>
</td>
<% } %>
<% if (docType.equals("word")) { %>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=blockcontent" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
.concat(request.getParameter("directUrl") != null ?
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=blockcontent" target="_blank">
<img src="css/img/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
@ -206,7 +214,9 @@
<% } %>
<% if (isFillFormDoc) { %>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=fillForms" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
.concat(request.getParameter("directUrl") != null ?
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=fillForms" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -216,7 +226,9 @@
<% } else if (isFillFormDoc) {%>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=mobile&mode=fillForms" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
.concat(request.getParameter("directUrl") != null ?
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=mobile&mode=fillForms" target="_blank">
<img src="css/img/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices" />
</a>
</td>
@ -224,24 +236,32 @@
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-icon "></td>
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=fillForms" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
.concat(request.getParameter("directUrl") != null ?
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=fillForms" target="_blank">
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
<% } else { %>
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
<% } %>
<td class="contentCells contentCells-icon firstContentCellViewers">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=view" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
.concat(request.getParameter("directUrl") != null ?
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=view" target="_blank">
<img src="css/img/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=mobile&mode=view" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
.concat(request.getParameter("directUrl") != null ?
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=mobile&mode=view" target="_blank">
<img src="css/img/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=embedded&mode=embedded" target="_blank">
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
.concat(request.getParameter("directUrl") != null ?
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=embedded&mode=embedded" target="_blank">
<img src="css/img/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery !== "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function() {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq("#fileupload").fileupload({
dataType: "json",
@ -218,7 +231,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?mode=edit&fileName=" + fileId;
var url = UrlEditor + "?mode=edit&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -226,7 +239,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?mode=view&fileName=" + fileId;
var url = UrlEditor + "?mode=view&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -234,7 +247,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?type=embedded&mode=embedded&fileName=" + fileId;
var url = UrlEditor + "?type=embedded&mode=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -287,6 +300,17 @@ if (typeof jQuery !== "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
var fileList = jq("tr.tableRow");
var mouseIsOverTooltip = false;
@ -302,7 +326,7 @@ if (typeof jQuery !== "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);

View File

@ -29,6 +29,7 @@ const config = require('config');
const configServer = config.get('server');
const storageFolder = configServer.get("storageFolder");
const mime = require("mime");
const urlModule = require("url");
const docManager = require("./helpers/docManager");
const documentService = require("./helpers/documentService");
const fileUtility = require("./helpers/fileUtility");
@ -469,6 +470,74 @@ app.get("/csv", function (req, res) { // define a handler for downloading csv f
filestream.pipe(res); // send file information to the response by streams
})
app.post("/reference", function (req, res) { //define a handler for renaming file
req.docManager = new docManager(req, res);
var result = function(data) {
res.writeHead(200, {"Content-Type": "application/json" });
res.write(JSON.stringify(data));
res.end();
};
var referenceData = req.body.referenceData;
if (!!referenceData) {
var portalName = referenceData.portalName;
if (portalName != req.docManager.getServerUrl()) {
result({ "error": "You do not have access to this site" });
return;
}
var fileId = JSON.parse(referenceData.fileId);
var userAddress = fileId.userAddress;
if (userAddress != req.docManager.curUserHostAddress()) {
result({ "error": "You do not have access to this file" });
return;
}
var fileName = fileId.fileName;
if (!req.docManager.existsSync(req.docManager.storagePath(fileName, userAddress))) {
result({ "error": "File is not exist" });
return;
}
} else if (!!req.body.link) {
if (req.body.link.indexOf(req.docManager.curUserHostAddress()) != -1) {
result({ "error": "You do not have access to this site" });
return;
}
var urlObj = urlModule.parse(req.body.link, true);
var fileName = urlObj.query.fileName;
if (!req.docManager.existsSync(req.docManager.storagePath(fileName, userAddress))) {
result({ "error": "File is not exist" });
return;
}
} else if (!!req.body.path) {
var fileName = fileUtility.getFileName(req.body.path);
if (!req.docManager.existsSync(req.docManager.storagePath(fileName, userAddress))) {
result({ "error": "File is not exist" });
return;
}
}
if (!fileName) {
result({ "error": "File is not found" });
return;
}
result({
url: req.docManager.getDownloadUrl(fileName, true),
directUrl: req.docManager.getDownloadUrl(fileName),
referenceData: {
fileId: JSON.stringify({ fileName: fileName, userAddress: req.docManager.curUserHostAddress()}),
portalName: req.docManager.getServerUrl()
},
link: req.docManager.getServerUrl() + "/editor?fileName=" + encodeURIComponent(fileName),
path: fileName,
});
});
app.post("/track", async function (req, res) { // define a handler for tracking file changes
req.docManager = new docManager(req, res);
@ -779,6 +848,19 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
}
}
var referenceData = {
fileId: JSON.stringify({ fileName: fileName, userAddress: req.docManager.curUserHostAddress()}),
portalName: req.docManager.getServerUrl()
};
var type = req.query.type || ""; // type: embedded/mobile/desktop
if (type == "") {
type = new RegExp(configServer.get("mobileRegEx"), "i").test(req.get('User-Agent')) ? "mobile" : "desktop";
} else if (type != "mobile"
&& type != "embedded") {
type = "desktop";
}
var templatesImageUrl = req.docManager.getTemplateImageUrl(fileUtility.getFileType(fileName));
var createUrl = req.docManager.getCreateUrl(fileUtility.getFileType(fileName), userid, type, lang);
var templates = [
@ -820,14 +902,6 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
var directUrl = req.docManager.getDownloadUrl(fileName);
var mode = req.query.mode || "edit"; // mode: view/edit/review/comment/fillForms/embedded
var type = req.query.type || ""; // type: embedded/mobile/desktop
if (type == "") {
type = new RegExp(configServer.get("mobileRegEx"), "i").test(req.get('User-Agent')) ? "mobile" : "desktop";
} else if (type != "mobile"
&& type != "embedded") {
type = "desktop";
}
var canEdit = configServer.get('editedDocs').indexOf(fileExt) != -1; // check if this file can be edited
if ((!canEdit && mode == "edit" || mode == "fillForms") && configServer.get('fillDocs').indexOf(fileExt) != -1) {
mode = "fillForms";
@ -945,7 +1019,8 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
fileChoiceUrl: fileChoiceUrl,
submitForm: submitForm,
plugins: JSON.stringify(plugins),
actionData: actionData
actionData: actionData,
referenceData: userid != "uid-0" ? referenceData : null
},
history: history,
historyData: historyData,

View File

@ -22,6 +22,7 @@
"commentGroups": <%- editor.commentGroups %>,
"userInfoGroups": <%- editor.userInfoGroups %>
},
"referenceData": <%- JSON.stringify(editor.referenceData) %>,
"title": "<%- file.name %>",
"url": "<%- file.uri %>"
},

View File

@ -151,6 +151,20 @@
innerAlert("onRequestSendNotify: " + data);
};
var onRequestReferenceData = function(event) { // user refresh external data source
innerAlert("onRequestReferenceData");
innerAlert(event.data);
let xhr = new XMLHttpRequest();
xhr.open("POST", "reference");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(event.data));
xhr.onload = function () {
innerAlert(xhr.responseText);
docEditor.setReferenceData(JSON.parse(xhr.responseText));
}
};
var onRequestSaveAs = function (event) { // the user is trying to save file by clicking Save Copy as... button
var title = event.data.title;
var url = event.data.url;
@ -209,6 +223,7 @@
config.events.onRequestRename = onRequestRename;
config.events.onRequestUsers = onRequestUsers;
config.events.onRequestSendNotify = onRequestSendNotify;
config.events.onRequestReferenceData = onRequestReferenceData;
}
if (config.editorConfig.createUrl) {

View File

@ -166,7 +166,7 @@ label .checkbox {
background-image: url("images/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}

View File

@ -26,6 +26,7 @@
$filename;
$user = getUser($_GET["user"]);
$isEnableDirectUrl = $_GET["directUrl"] != null ? filter_var($_GET["directUrl"], FILTER_VALIDATE_BOOLEAN) : false;
// get the file url and upload it
$externalUrl = $_GET["fileUrl"];
@ -90,7 +91,7 @@
"document" => [
"title" => $filename,
"url" => getDownloadUrl($filename),
"directUrl" => $directUrl,
"directUrl" => $isEnableDirectUrl ? $directUrl : "",
"fileType" => $filetype,
"key" => $docKey,
"info" => [
@ -150,24 +151,33 @@
];
// an image for inserting
$dataInsertImage = [
$dataInsertImage = $isEnableDirectUrl ? [
"fileType" => "png",
"url" => serverPath(true) . "/css/images/logo.png",
"directUrl" => serverPath(false) . "/css/images/logo.png"
] : [
"fileType" => "png",
"url" => serverPath(true) . "/css/images/logo.png"
];
// a document for comparing
$dataCompareFile = [
$dataCompareFile = $isEnableDirectUrl ? [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=assets&name=sample.docx"
] : [
"fileType" => "docx",
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx"
];
// recipients data for mail merging
$dataMailMergeRecipients = [
$dataMailMergeRecipients = $isEnableDirectUrl ? [
"fileType" =>"csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv",
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=csv"
] : [
"fileType" =>"csv",
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv"
];
// users data for mentions
@ -240,7 +250,7 @@
}
// get document history
function getHistory($filename, $filetype, $docKey, $fileuri) {
function getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl) {
$storagePath = $GLOBALS['STORAGE_PATH'];
$histDir = getHistoryDir(getStoragePath($filename)); // get the path to the file history
@ -282,11 +292,15 @@
$prevFileUrl = $i == $curVer ? $fileuri : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
if (realpath($storagePath) === $storagePath) {
$prevFileUrl = $i == $curVer ? getDownloadUrl($filename) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
$directUrl = $i == $curVer ? getDownloadUrl($filename, FALSE) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, FALSE);
if ($isEnableDirectUrl) {
$directUrl = $i == $curVer ? getDownloadUrl($filename, FALSE) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, FALSE);
}
}
$dataObj["url"] = $prevFileUrl; // write file url to the data object
$dataObj["directUrl"] = $directUrl; // write direct url to the data object
if ($isEnableDirectUrl) {
$dataObj["directUrl"] = $directUrl; // write direct url to the data object
}
$dataObj["version"] = $i;
if ($i > 1) { // check if the version number is greater than 1 (the document was modified)
@ -299,11 +313,15 @@
$obj["user"] = $change ? $change["user"] : null;
$prev = $histData[$i - 2]; // get the history data from the previous file version
$dataObj["previous"] = [ // write information about previous file version to the data object
$dataObj["previous"] = $isEnableDirectUrl ? [ // write information about previous file version to the data object
"fileType" => $prev["fileType"],
"key" => $prev["key"],
"url" => $prev["url"],
"directUrl" => $prev["directUrl"]
] : [
"fileType" => $prev["fileType"],
"key" => $prev["key"],
"url" => $prev["url"]
];
// write the path to the diff.zip archive with differences in this file version
@ -529,7 +547,7 @@
};
<?php
$out = getHistory($filename, $filetype, $docKey, $fileuri);
$out = getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl);
$history = $out[0];
$historyData = $out[1];
?>

View File

@ -23,6 +23,7 @@
require_once( dirname(__FILE__) . '/users.php' );
$user = $_GET["user"];
$directUrlArg = $_GET["directUrl"] != null ? "&directUrl=" . $_GET["directUrl"] : "";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@ -73,7 +74,7 @@
<a class="try-editor form reload-page" target="_blank" href="doceditor.php?fileExt=docxf&user=<?php echo htmlentities($user); ?>">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input type="checkbox" id="createSample" class="checkbox" />With sample content
</label>
</div>
@ -87,7 +88,7 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" src="css/images/info.svg" />
<img id="info" src="css/images/info.svg" />
<select class="select-user" id="user">
<?php foreach(getAllUsers() as $user_l) {
$name = $user_l->name ? $user_l->name : "Anonymous";
@ -106,6 +107,14 @@
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="css/images/info.svg" />
</label>
</td>
</tr>
</table>
</div>
</div>
@ -159,37 +168,37 @@
<?php foreach ($storedFiles as &$storeFile) {
echo '<tr class="tableRow" title="'.$storeFile->name.' ['.getFileVersion(getHistoryDir(getStoragePath($storeFile->name))).']">';
echo ' <td class="contentCells">';
echo ' <a class="stored-edit '.$storeFile->documentType.'" href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'" target="_blank">';
echo ' <a class="stored-edit '.$storeFile->documentType.'" href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg .'" target="_blank">';
echo ' <span>'.$storeFile->name.'</span>';
echo ' </a>';
echo ' </td>';
if ($storeFile->canEdit) {
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=edit&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=edit&type=desktop" target="_blank">';
echo ' <img src="css/images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=edit&type=mobile" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=edit&type=mobile" target="_blank">';
echo ' <img src="css/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=comment&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=comment&type=desktop" target="_blank">';
echo ' <img src="css/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment" /></a>';
echo ' </td>';
if ($storeFile->documentType == "word") {
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=review&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=review&type=desktop" target="_blank">';
echo ' <img src="css/images/review.svg" alt="Open in editor for review" title="Open in editor for review" /></a>';
echo ' </td>';
} else if ($storeFile->documentType == "cell") {
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=filter&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=filter&type=desktop" target="_blank">';
echo ' <img src="css/images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" /></a>';
echo ' </td>';
}
if ($storeFile->documentType == "word") {
echo ' <td class="contentCells contentCells-icon ">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=blockcontent&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=blockcontent&type=desktop" target="_blank">';
echo ' <img src="css/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification" /></a>';
echo ' </td>';
} else{
@ -200,7 +209,7 @@
}
if ($storeFile->isFillFormDoc) {
echo ' <td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=fillForms&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
echo ' <img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>';
echo ' </td>';
} else {
@ -209,29 +218,29 @@
} else if ($storeFile->isFillFormDoc) {
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=fillForms&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
echo ' <img src="css/images/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-icon"></td>';
echo ' <td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=fillForms&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
echo ' <img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>';
echo ' </td>';
} else {
echo '<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>';
}
echo ' <td class="contentCells contentCells-icon firstContentCellViewers">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'&action=view&type=desktop" target="_blank">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=view&type=desktop" target="_blank">';
echo ' <img src="css/images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'&action=view&type=mobile" target="_blank">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=view&type=mobile" target="_blank">';
echo ' <img src="css/images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon contentCells-shift">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'&action=embedded&type=embedded" target="_blank">';
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=embedded&type=embedded" target="_blank">';
echo ' <img src="css/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode" /></a>';
echo ' </td>';
echo ' <td class="contentCells contentCells-icon contentCells-shift downloadContentCellShift">';

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery != "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function() {
window.location = "?directUrl=" + jq(this).prop("checked");
});
user = getUrlVars()["user"];
if ("" != user && undefined != user)
jq("#user").val(user);
@ -234,7 +247,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.php?fileID=" + fileId + "&user=" + user;
var url = "doceditor.php?fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -243,7 +256,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.php?action=view&fileID=" + fileId + "&user=" + user;
var url = "doceditor.php?action=view&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -252,7 +265,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = "doceditor.php?type=embedded&fileID=" + fileId + "&user=" + user;
var url = "doceditor.php?type=embedded&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");

View File

@ -115,7 +115,8 @@ function processSave($data, $fileName, $userAddress) {
$saved = 1;
if (!(($new_data = file_get_contents($downloadUri)) === FALSE)) {
if (!(($new_data = file_get_contents($downloadUri, false,
stream_context_create(["http"=>["timeout"=>5]]))) === FALSE)) {
$storagePath = getStoragePath($newFileName, $userAddress); // get the file path
$histDir = getHistoryDir($storagePath); // get the path to the history direction
$verDir = getVersionDir($histDir, getFileVersion($histDir)); // get the path to the file version
@ -125,7 +126,8 @@ function processSave($data, $fileName, $userAddress) {
rename(getStoragePath($fileName, $userAddress), $verDir . DIRECTORY_SEPARATOR . "prev" . $curExt); // get the path to the previous file version and rename the storage path with it
file_put_contents($storagePath, $new_data, LOCK_EX); // save file to the storage directory
if ($changesData = file_get_contents($data->changesurl)) {
if ($changesData = file_get_contents($data->changesurl, false,
stream_context_create(["http"=>["timeout"=>5]]))) {
file_put_contents($verDir . DIRECTORY_SEPARATOR . "diff.zip", $changesData, LOCK_EX); // save file changes to the diff.zip archive
}
@ -190,7 +192,8 @@ function processForceSave($data, $fileName, $userAddress) {
$saved = 1;
if (!(($new_data = file_get_contents($downloadUri)) === FALSE)) {
if (!(($new_data = file_get_contents($downloadUri, false,
stream_context_create(["http"=>["timeout"=>5]]))) === FALSE)) {
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
$isSubmitForm = $data->forcesavetype == 3; // SubmitForm

View File

@ -211,7 +211,9 @@ def createFile(stream, path, req = None, meta = False):
# create file response
def createFileResponse(response, path, req, meta):
response.raise_for_status()
status_code = response.status_code
if status_code != 200: # checking status code
raise RuntimeError('Document editing service returned status: %s' % status_code)
with open(path, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
file.write(chunk)
@ -219,7 +221,7 @@ def createFileResponse(response, path, req, meta):
# save file from the given url
def saveFileFromUri(uri, path, req = None, meta = False):
resp = requests.get(uri, stream=True, verify = config.DOC_SERV_VERIFY_PEER)
resp = requests.get(uri, stream=True, verify = config.DOC_SERV_VERIFY_PEER, timeout=5)
createFileResponse(resp, path, req, meta)
return

View File

@ -152,7 +152,7 @@ def getMeta(storagePath):
return None
# get the document history of a given file
def getHistoryObject(storagePath, filename, docKey, docUrl, req):
def getHistoryObject(storagePath, filename, docKey, docUrl, isEnableDirectUrl, req):
histDir = getHistoryDir(storagePath)
version = getFileVersion(histDir)
if version > 0: # if the file was modified (the file version is greater than 0)
@ -184,7 +184,8 @@ def getHistoryObject(storagePath, filename, docKey, docUrl, req):
}
dataObj['url'] = docUrl if i == version else getPublicHistUri(filename, i, "prev" + fileUtils.getFileExt(filename), req) # write file url to the data object
dataObj['directUrl'] = docManager.getDownloadUrl(filename, req, False) if i == version else getPublicHistUri(filename, i, "prev" + fileUtils.getFileExt(filename), req, False) # write file direct url to the data object
if isEnableDirectUrl:
dataObj['directUrl'] = docManager.getDownloadUrl(filename, req, False) if i == version else getPublicHistUri(filename, i, "prev" + fileUtils.getFileExt(filename), req, False) # write file direct url to the data object
if i > 1: # check if the version number is greater than 1 (the file was modified)
changes = json.loads(readFile(getChangesHistoryPath(prevVerDir))) # get the path to the changes.json file
@ -201,6 +202,10 @@ def getHistoryObject(storagePath, filename, docKey, docUrl, req):
'key': prev['key'],
'url': prev['url'],
'directUrl': prev['directUrl']
} if isEnableDirectUrl else { # write key and url information about previous file version
'fileType': prev['fileType'],
'key': prev['key'],
'url': prev['url']
}
dataObj['previous'] = prevInfo # write information about previous file version to the data object
dataObj['changesUrl'] = getPublicHistUri(filename, i - 1, "diff.zip", req) # write the path to the diff.zip archive with differences in this file version

View File

@ -58,7 +58,10 @@ def getConverterUri(docUri, fromExt, toExt, docKey, isAsync, filePass = None, la
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers, verify = config.DOC_SERV_VERIFY_PEER) # send the headers and body values to the converter and write the result to the response
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers, verify = config.DOC_SERV_VERIFY_PEER, timeout=5) # send the headers and body values to the converter and write the result to the response
status_code = response.status_code
if status_code != 200: # checking status code
raise RuntimeError('Convertation service returned status: %s' % status_code)
json = response.json()
return getResponseUri(json)

View File

@ -171,6 +171,7 @@ def rename(request):
# edit a file
def edit(request):
filename = fileUtils.getFileName(request.GET['filename'])
isEnableDirectUrl = request.GET['directUrl'].lower() in ("true") if 'directUrl' in request.GET else False
ext = fileUtils.getFileExt(filename)
@ -234,7 +235,7 @@ def edit(request):
'document': {
'title': filename,
'url': docManager.getDownloadUrl(filename, request),
'directUrl': directUrl,
'directUrl': directUrl if isEnableDirectUrl else "",
'fileType': ext[1:],
'key': docKey,
'info': infObj,
@ -295,6 +296,9 @@ def edit(request):
'fileType': 'png',
'url': docManager.getServerUrl(True, request) + 'static/images/logo.png',
'directUrl': docManager.getServerUrl(False, request) + 'static/images/logo.png'
} if isEnableDirectUrl else {
'fileType': 'png',
'url': docManager.getServerUrl(True, request) + 'static/images/logo.png'
}
# a document which will be compared with the current document
@ -302,6 +306,9 @@ def edit(request):
'fileType': 'docx',
'url': docManager.getServerUrl(True, request) + 'static/sample.docx',
'directUrl': docManager.getServerUrl(False, request) + 'static/sample.docx'
} if isEnableDirectUrl else {
'fileType': 'docx',
'url': docManager.getServerUrl(True, request) + 'static/sample.docx'
}
# recipient data for mail merging
@ -309,6 +316,9 @@ def edit(request):
'fileType': 'csv',
'url': docManager.getServerUrl(True, request) + 'csv',
'directUrl': docManager.getServerUrl(False, request) + 'csv'
} if isEnableDirectUrl else {
'fileType': 'csv',
'url': docManager.getServerUrl(True, request) + 'csv'
}
# users data for mentions
@ -320,7 +330,7 @@ def edit(request):
dataCompareFile['token'] = jwtManager.encode(dataCompareFile) # encode the dataCompareFile object into a token
dataMailMergeRecipients['token'] = jwtManager.encode(dataMailMergeRecipients) # encode the dataMailMergeRecipients object into a token
hist = historyManager.getHistoryObject(storagePath, filename, docKey, fileUri, request) # get the document history
hist = historyManager.getHistoryObject(storagePath, filename, docKey, fileUri, isEnableDirectUrl, request) # get the document history
context = { # the data that will be passed to the template
'cfg': json.dumps(edConfig), # the document config in json format
@ -358,8 +368,8 @@ def track(request):
trackManager.processForceSave(body, filename, usAddr)
except Exception as e:
response.setdefault('error', 1) # set the default error value as 1 (document key is missing or no document with such key could be found)
response.setdefault('message', e.args[0])
response.setdefault("error", 1) # set the default error value as 1 (document key is missing or no document with such key could be found)
response.setdefault("message", str(e.args[0]))
response.setdefault('error', 0) # if no exceptions are raised, the default error value is 0 (no errors)
# the response status is 200 if the changes are saved successfully; otherwise, it is equal to 500

View File

@ -24,6 +24,8 @@
"""
import re
import sys
import config
import json
@ -32,6 +34,12 @@ from django.shortcuts import render
from src.utils import users
from src.utils import docManager
def getDirectUrlParam(request):
if ('directUrl' in request.GET):
return request.GET['directUrl'].lower() in ("true")
else:
return False;
def default(request): # default parameters that will be passed to the template
context = {
'users': users.USERS,
@ -40,6 +48,7 @@ def default(request): # default parameters that will be passed to the template
'editExt': json.dumps(config.DOC_SERV_EDITED), # file extensions that can be edited
'convExt': json.dumps(config.DOC_SERV_CONVERT), # file extensions that can be converted
'files': docManager.getStoredFiles(request), # information about stored files
'fillExt': json.dumps(config.DOC_SERV_FILLFORMS)
'fillExt': json.dumps(config.DOC_SERV_FILLFORMS),
'directUrl': str(getDirectUrlParam(request)).lower
}
return render(request, 'index.html', context) # execute the "index.html" template with context data and return http response in json format

View File

@ -175,7 +175,7 @@ label .checkbox {
background-image: url("../images/file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}

View File

@ -24,11 +24,24 @@
*
*/
var directUrl;
if (typeof jQuery !== "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function() {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq("#fileupload").fileupload({
dataType: "json",
@ -226,7 +239,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?mode=edit&filename=" + fileId;
var url = UrlEditor + "?mode=edit&filename=" + fileId+ "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -234,7 +247,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?mode=view&filename=" + fileId;
var url = UrlEditor + "?mode=view&filename=" + fileId+ "&directUrl=" + directUrl;
window.open(url, "_blank");
jq("#hiddenFileName").val("");
jq.unblockUI();
@ -242,7 +255,7 @@ if (typeof jQuery !== "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
var url = UrlEditor + "?type=embedded&mode=embedded&filename=" + fileId;
var url = UrlEditor + "?type=embedded&mode=embedded&filename=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -309,7 +322,7 @@ if (typeof jQuery !== "undefined") {
});
}
} else {
jq(".info").mouseover(function (event) {
jq("#info").mouseover(function (event) {
if (fileList.length > 0) {
if (hideTooltipTimeout != null) {
clearTimeout(hideTooltipTimeout);
@ -333,4 +346,15 @@ if (typeof jQuery !== "undefined") {
}, 500);
});
}
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
}

View File

@ -71,7 +71,7 @@
<a class="try-editor form reload-page" target="_blank" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input type="checkbox" id="createSample" class="checkbox" />With sample content
</label>
</div>
@ -86,7 +86,7 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" src="{% static "images/info.svg" %}" />
<img id="info" src="{% static "images/info.svg" %}" />
<select class="select-user" id="user">
{% for user in users %}
<option value="{{ user.id }}">{% if user.name %} {{ user.name }} {% else %} Anonymous {% endif %} </option>
@ -104,6 +104,14 @@
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="{% static "images/info.svg" %}" />
</label>
</td>
</tr>
</table>
</div>
</div>
@ -153,42 +161,42 @@
{% for file in files %}
<tr class="tableRow" title="{{ file.title }} [{{file.version}}]">
<td class="contentCells">
<a class="stored-edit {{ file.type }}" href="edit?filename={{ file.title }}" target="_blank">
<a class="stored-edit {{ file.type }}" href="edit?filename={{ file.title }}&directUrl={{ directUrl }}" target="_blank">
<span>{{ file.title }}</span>
</a>
</td>
{% if file.canEdit %}
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=desktop&mode=edit" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=edit&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/desktop.svg" %}" alt="Open in editor for full size screens" title="Open in editor for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=mobile&mode=edit" target="_blank">
<a href="edit?filename={{ file.title }}&type=mobile&mode=edit&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/mobile.svg" %}" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=desktop&mode=comment" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=comment&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/comment.svg" %}" alt="Open in editor for comment" title="Open in editor for comment"/>
</a>
</td>
{% if file.type == 'word' %}
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=desktop&mode=review" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=review&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/review.svg" %}" alt="Open in editor for review" title="Open in editor for review"/>
</a>
</td>
{% elif file.type == 'cell' %}
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=desktop&mode=filter" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=filter&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/filter.svg" %}" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
</a>
</td>
{% endif %}
{% if file.type == 'word' %}
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=desktop&mode=blockcontent" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=blockcontent&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/block-content.svg" %}" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
</a>
</td>
@ -200,7 +208,7 @@
{% endif %}
{% if file.isFillFormDoc %}
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/fill-forms.svg" %}" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -210,7 +218,7 @@
{% elif file.isFillFormDoc %}
<td class="contentCells contentCells-icon"></td>
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=mobile&mode=fillForms" target="_blank">
<a href="edit?filename={{ file.title }}&type=mobile&mode=fillForms&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/mobile-fill-forms.svg" %}" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices"/>
</a>
</td>
@ -218,7 +226,7 @@
<td class="contentCells contentCells-icon"></td>
<td class="contentCells contentCells-icon"></td>
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/fill-forms.svg" %}" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
</a>
</td>
@ -226,17 +234,17 @@
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
{% endif %}
<td class="contentCells contentCells-icon firstContentCellViewers">
<a href="edit?filename={{ file.title }}&type=desktop&mode=view" target="_blank">
<a href="edit?filename={{ file.title }}&type=desktop&mode=view&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/desktop.svg" %}" alt="Open in viewer for full size screens" title="Open in viewer for full size screens"/>
</a>
</td>
<td class="contentCells contentCells-icon">
<a href="edit?filename={{ file.title }}&type=mobile&mode=view" target="_blank">
<a href="edit?filename={{ file.title }}&type=mobile&mode=view&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/mobile.svg" %}" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices"/>
</a>
</td>
<td class="contentCells contentCells-icon contentCells-shift">
<a href="edit?filename={{ file.title }}&type=embedded&mode=embedded" target="_blank">
<a href="edit?filename={{ file.title }}&type=embedded&mode=embedded&directUrl={{ directUrl }}" target="_blank">
<img src="{% static "images/embeded.svg" %}" alt="Open in embedded mode" title="Open in embedded mode"/>
</a>
</td>

View File

@ -16,11 +16,24 @@
*
*/
var directUrl;
if (typeof jQuery != "undefined") {
jq = jQuery.noConflict();
directUrl = getUrlVars()["directUrl"] == "true";
mustReload = false;
if (directUrl)
jq("#directUrl").prop("checked", directUrl);
else
directUrl = jq("#directUrl").prop("checked");
jq("#directUrl").change(function() {
window.location = "?directUrl=" + jq(this).prop("checked");
});
jq(function () {
jq('#fileupload').fileupload({
dataType: 'json',
@ -218,7 +231,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEdit:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?fileName=" + fileId;
var url = UrlEditor + "?fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -226,7 +239,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginView:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId;
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId + "&directUrl=" + directUrl;
window.open(url, "_blank");
jq('#hiddenFileName').val("");
jq.unblockUI();
@ -234,7 +247,7 @@ if (typeof jQuery != "undefined") {
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId;
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
jq("#mainProgress").addClass("embedded");
jq("#beginEmbedded").addClass("disable");
@ -286,6 +299,17 @@ if (typeof jQuery != "undefined") {
}
};
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
};
var fileList = jq("tr.tableRow");
var mouseIsOverTooltip = false;

View File

@ -168,7 +168,7 @@ label .checkbox {
background-image: url("file_docxf.svg");
}
.create-sample {
.side-option {
color: #666666;
line-height: 24px;
}

View File

@ -26,7 +26,7 @@ class HomeController < ApplicationController
DocumentHelper.init(request.remote_ip, request.base_url)
user = Users.get_user(cookies[:uid])
@file = FileModel.new(:file_name => File.basename(params[:fileName]), :mode => params[:editorsMode], :type => params[:editorsType], :user_ip => request.remote_ip, :lang => cookies[:ulang], :user => user, :action_data => params[:actionLink])
@file = FileModel.new(:file_name => File.basename(params[:fileName]), :mode => params[:editorsMode], :type => params[:editorsType], :user_ip => request.remote_ip, :lang => cookies[:ulang], :user => user, :action_data => params[:actionLink], :direct_url => params[:directUrl])
end

View File

@ -16,7 +16,7 @@
class FileModel
attr_accessor :file_name, :mode, :type, :user_ip, :lang, :user, :action_data
attr_accessor :file_name, :mode, :type, :user_ip, :lang, :user, :action_data, :direct_url
# set file parameters
def initialize(attributes = {})
@ -27,6 +27,7 @@ class FileModel
@lang = attributes[:lang]
@user = attributes[:user]
@action_data = attributes[:action_data]
@direct_url = attributes[:direct_url]
end
def type
@ -110,7 +111,7 @@ class FileModel
:document => {
:title => @file_name,
:url => download_url,
:directUrl => download_url(false),
:directUrl => is_enable_direct_url ? download_url(false) : "",
:fileType => file_ext.delete("."),
:key => key,
:info => {
@ -224,7 +225,9 @@ class FileModel
dataObj["fileType"] = file_ext[1..file_ext.length]
dataObj["key"] = cur_key
dataObj["url"] = i == cur_ver ? doc_uri : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}")
dataObj["directUrl"] = i == cur_ver ? download_url(false) : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}", false)
if is_enable_direct_url == true
dataObj["directUrl"] = i == cur_ver ? download_url(false) : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}", false)
end
dataObj["version"] = i
if (i > 1) # check if the version number is greater than 1
@ -243,11 +246,15 @@ class FileModel
obj["user"] = change ? change["user"] : nil
prev = histData[(i - 2).to_s] # get the history data from the previous file version
dataObj["previous"] = { # write key and url information about previous file version
dataObj["previous"] = is_enable_direct_url == true ? { # write key and url information about previous file version with optional direct url
:fileType => prev["fileType"],
:key => prev["key"],
:url => prev["url"],
:directUrl => prev["directUrl"]
} : {
:fileType => prev["fileType"],
:key => prev["key"],
:url => prev["url"]
}
# write the path to the diff.zip archive with differences in this file version
@ -276,11 +283,14 @@ class FileModel
end
# get image information
def get_insert_image
insert_image = {
def get_insert_image
insert_image = is_enable_direct_url == true ? {
:fileType => "png", # image file type
:url => DocumentHelper.get_server_url(true) + "/assets/logo.png", # server url to the image
:directUrl => DocumentHelper.get_server_url(false) + "/assets/logo.png" # direct url to the image
} : {
:fileType => "png", # image file type
:url => DocumentHelper.get_server_url(true) + "/assets/logo.png" # server url to the image
}
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
@ -292,10 +302,13 @@ class FileModel
# get compared file information
def get_compare_file
compare_file = {
compare_file = is_enable_direct_url == true ? {
:fileType => "docx", # file type
:url => DocumentHelper.get_server_url(true) + "/assets/sample/sample.docx", # server url to the compared file
:directUrl => DocumentHelper.get_server_url(false) + "/assets/sample/sample.docx" # direct url to the compared file
} : {
:fileType => "docx", # file type
:url => DocumentHelper.get_server_url(true) + "/assets/sample/sample.docx" # server url to the compared file
}
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
@ -307,10 +320,13 @@ class FileModel
# get mail merge recipients information
def dataMailMergeRecipients
dataMailMergeRecipients = {
dataMailMergeRecipients = is_enable_direct_url == true ? {
:fileType => "csv", # file type
:url => DocumentHelper.get_server_url(true) + "/csv", # server url to the mail merge recipients file
:directUrl => DocumentHelper.get_server_url(false) + "/csv" # direct url to the mail merge recipients file
} : {
:fileType => "csv", # file type
:url => DocumentHelper.get_server_url(true) + "/csv" # server url to the mail merge recipients file
}
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
@ -325,4 +341,9 @@ class FileModel
return !@user.id.eql?("uid-0") ? Users.get_users_for_mentions(@user.id) : nil
end
# get direct url existence flag
def is_enable_direct_url
return @direct_url != nil && @direct_url == "true"
end
end

View File

@ -54,6 +54,7 @@ class ServiceConverter
DocumentHelper.verify_ssl(@@document_converter_url, http)
http.read_timeout = @@convert_timeout
http.open_timeout = 5
req = Net::HTTP::Post.new(uri.request_uri) # create the post request
req.add_field("Accept", "application/json") # set headers
req.add_field("Content-Type", "application/json")
@ -66,6 +67,12 @@ class ServiceConverter
req.body = payload.to_json
res = http.request(req) # get the response
status_code = res.code
if status_code != 200 # checking status code
raise "Conversion service returned status: #{status_code}"
end
data = res.body # and take its body
rescue TimeoutError
# try again

View File

@ -251,11 +251,17 @@ class TrackHelper
def save_from_uri(path, uristr)
uri = URI.parse(uristr) # parse the url string
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
http.open_timeout = 5
DocumentHelper.verify_ssl(uristr, http)
req = Net::HTTP::Get.new(uri)
res = http.request(req) # get the response
status_code = res.code
if status_code != 200 # checking status code
raise "Document editing service returned status: #{status_code}"
end
data = res.body # and take its body
if data == nil

View File

@ -44,7 +44,7 @@
<a class="try-editor form" data-type="docxf">Form template</a>
</li>
</ul>
<label class="create-sample">
<label class="side-option">
<input id="createSample" class="checkbox" type="checkbox" />With sample content
</label>
</div>
@ -60,7 +60,7 @@
<tr>
<td valign="middle">
<span class="select-user">Username</span>
<img class="info" data-id="user" src="assets/info.svg" />
<img id="info" data-id="user" src="assets/info.svg" />
<select class="select-user" id="user">
<% for user in Users.get_all_users() do %>
<option value="<%= user.id %>"><%= user.name ? user.name : "Anonymous" %></option>
@ -78,6 +78,14 @@
</select>
</td>
</tr>
<tr>
<td valign="middle">
<label class="side-option">
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="assets/info.svg" />
</label>
</td>
</tr>
</tbody>
</table>
</div>
@ -87,6 +95,7 @@
<%
DocumentHelper.init(request.remote_ip, request.base_url)
docs = DocumentHelper.get_stored_files(nil)
directUrl = request.params[:directUrl]
%>
<div class="main-panel">
<div id="portal-info" style="display: <%= docs.length > 0 ? "none" : "table-cell" %>">
@ -128,7 +137,7 @@
<%
docs.each { |d|
isFillFormDoc = DocumentHelper.fill_forms_exts.include?(File.extname(d).downcase)
editUrl = "editor?fileName=#{ERB::Util.url_encode(d)}"
editUrl = directUrl == nil ? "editor?fileName=#{ERB::Util.url_encode(d)}" : "editor?fileName=#{ERB::Util.url_encode(d)}&directUrl=#{directUrl}"
docType = FileUtility.get_file_type(d)
canEdit = DocumentHelper.edited_exts.include?(File.extname(d).downcase) %>
<tr class="tableRow" title="<%= d %> [<%= DocumentHelper.get_file_version(DocumentHelper.history_dir(DocumentHelper.storage_path(d, nil))) %>]">