Files: moved from feature/editor-version-history

This commit is contained in:
pavelbannov 2021-12-08 15:25:39 +03:00
parent 475dd92c30
commit feb48c01a0
7 changed files with 353 additions and 222 deletions

View File

@ -97,7 +97,7 @@ namespace ASC.Files.Core.Data
services.TryAdd<ILinkDao, LinkDao>();
// AddSharpBoxDaoSelectorService
services.TryAdd<EditHistory>();
}
}
}

View File

@ -1202,14 +1202,12 @@ namespace ASC.Files.Core.Data
.Select(r =>
{
var item = ServiceProvider.GetService<EditHistory>();
var editHistoryAuthor = ServiceProvider.GetService<EditHistoryAuthor>();
editHistoryAuthor.Id = r.ModifiedBy;
item.ID = r.Id;
item.Version = r.Version;
item.VersionGroup = r.VersionGroup;
item.ModifiedOn = TenantUtil.DateTimeFromUtc(r.ModifiedOn);
item.ModifiedBy = editHistoryAuthor;
item.ModifiedBy = r.ModifiedBy;
item.ChangesString = r.Changes;
item.Key = documentServiceHelper.GetDocKey(item.ID, item.Version, TenantUtil.DateTimeFromUtc(r.CreateOn));

View File

@ -1,221 +1,225 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.Json.Serialization;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Core.Tenants;
using ASC.Core.Users;
using ASC.Files.Core.Resources;
using ASC.Web.Core.Users;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
namespace ASC.Files.Core
{
[DebuggerDisplay("{ID} v{Version}")]
public class EditHistory
{
public EditHistory(
IOptionsMonitor<ILog> options,
TenantUtil tenantUtil,
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper)
{
Logger = options.CurrentValue;
TenantUtil = tenantUtil;
UserManager = userManager;
DisplayUserSettingsHelper = displayUserSettingsHelper;
}
public int ID { get; set; }
public string Key { get; set; }
public int Version { get; set; }
public int VersionGroup { get; set; }
[JsonPropertyName("user")]
public EditHistoryAuthor ModifiedBy { get; set; }
[JsonPropertyName("changeshistory")]
public string ChangesString { get; set; }
public List<EditHistoryChanges> Changes
{
get
{
var changes = new List<EditHistoryChanges>();
if (string.IsNullOrEmpty(ChangesString)) return changes;
try
{
var jObject = JObject.Parse(ChangesString);
ServerVersion = jObject.Value<string>("serverVersion");
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using ASC.Common;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Core.Tenants;
using ASC.Core.Users;
using ASC.Files.Core.Resources;
using ASC.Web.Core.Users;
using Microsoft.Extensions.Options;
namespace ASC.Files.Core
{
[Transient]
[DebuggerDisplay("{ID} v{Version}")]
public class EditHistory
{
private ILog Logger { get; }
private TenantUtil TenantUtil { get; }
private UserManager UserManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
public EditHistory(
IOptionsMonitor<ILog> options,
TenantUtil tenantUtil,
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper)
{
Logger = options.CurrentValue;
TenantUtil = tenantUtil;
UserManager = userManager;
DisplayUserSettingsHelper = displayUserSettingsHelper;
}
public int ID { get; set; }
public string Key { get; set; }
public int Version { get; set; }
public int VersionGroup { get; set; }
public DateTime ModifiedOn { get; set; }
public Guid ModifiedBy { get; set; }
public string ChangesString { get; set; }
public string ServerVersion { get; set; }
public List<EditHistoryChanges> Changes
{
get
{
var changes = new List<EditHistoryChanges>();
if (string.IsNullOrEmpty(ChangesString)) return changes;
try
{
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
var jObject = JsonSerializer.Deserialize<ChangesDataList>(ChangesString, options);
ServerVersion = jObject.ServerVersion;
if (string.IsNullOrEmpty(ServerVersion))
return changes;
var jChanges = jObject.Value<JArray>("changes");
changes = jChanges.Children()
.Select(jChange =>
{
var jUser = jChange.Value<JObject>("user");
return new EditHistoryChanges(TenantUtil)
{
Date = jChange.Value<string>("created"),
Author = new EditHistoryAuthor(UserManager, DisplayUserSettingsHelper)
{
Id = new Guid(jUser.Value<string>("id") ?? Guid.Empty.ToString()),
Name = jUser.Value<string>("name"),
},
};
})
.ToList();
return changes;
}
catch (Exception ex)
{
Logger.Error("DeSerialize old scheme exception", ex);
}
return changes;
}
set { throw new NotImplementedException(); }
}
public DateTime ModifiedOn;
[JsonPropertyName("created")]
public string ModifiedOnString
{
get { return ModifiedOn.Equals(default) ? null : ModifiedOn.ToString("g"); }
set { throw new NotImplementedException(); }
}
public ILog Logger { get; }
private TenantUtil TenantUtil { get; }
private UserManager UserManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
public string ServerVersion;
}
[DebuggerDisplay("{Id} {Name}")]
public class EditHistoryAuthor
{
public EditHistoryAuthor(
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper)
{
UserManager = userManager;
DisplayUserSettingsHelper = displayUserSettingsHelper;
}
public Guid Id { get; set; }
private string _name;
public string Name
{
get
{
UserInfo user;
return
Id.Equals(Guid.Empty)
|| Id.Equals(ASC.Core.Configuration.Constants.Guest.ID)
|| (user = UserManager.GetUsers(Id)).Equals(Constants.LostUser)
? string.IsNullOrEmpty(_name)
? FilesCommonResource.Guest
: _name
: user.DisplayUserName(false, DisplayUserSettingsHelper);
}
set { _name = value; }
}
private UserManager UserManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
}
[DebuggerDisplay("{Author.Name}")]
public class EditHistoryChanges
{
public EditHistoryChanges(TenantUtil tenantUtil)
{
TenantUtil = tenantUtil;
}
[JsonPropertyName("user")]
public EditHistoryAuthor Author { get; set; }
private DateTime _date;
[JsonPropertyName("created")]
public string Date
{
get { return _date.Equals(default) ? null : _date.ToString("g"); }
set
{
if (DateTime.TryParse(value, out _date))
{
_date = TenantUtil.DateTimeFromUtc(_date);
}
}
}
private TenantUtil TenantUtil { get; }
}
[DebuggerDisplay("{Version}")]
public class EditHistoryData
{
public string ChangesUrl { get; set; }
public string Key { get; set; }
public EditHistoryUrl Previous { get; set; }
public string Token { get; set; }
public string Url { get; set; }
public int Version { get; set; }
}
[DebuggerDisplay("{Key} - {Url}")]
public class EditHistoryUrl
{
public string Key { get; set; }
public string Url { get; set; }
}
changes = jObject.Changes.Select(r =>
{
var result = new EditHistoryChanges()
{
Author = new EditHistoryAuthor(UserManager, DisplayUserSettingsHelper)
{
Id = new Guid(r.User.Id ?? Guid.Empty.ToString()),
Name = r.User.Name,
}
};
if (DateTime.TryParse(r.Created, out var _date))
{
_date = TenantUtil.DateTimeFromUtc(_date);
}
result.Date = _date;
return result;
})
.ToList();
return changes;
}
catch (Exception ex)
{
Logger.Error("DeSerialize old scheme exception", ex);
}
return changes;
}
set { throw new NotImplementedException(); }
}
}
class ChangesDataList
{
public string ServerVersion { get; set; }
public ChangesData[] Changes { get; set; }
}
class ChangesData
{
public string Created { get; set; }
public ChangesUserData User { get; set; }
}
class ChangesUserData
{
public string Id { get; set; }
public string Name { get; set; }
}
[Transient]
[DebuggerDisplay("{Id} {Name}")]
public class EditHistoryAuthor
{
public EditHistoryAuthor(
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper)
{
UserManager = userManager;
DisplayUserSettingsHelper = displayUserSettingsHelper;
}
public Guid Id { get; set; }
private string _name;
public string Name
{
get
{
UserInfo user;
return
Id.Equals(Guid.Empty)
|| Id.Equals(ASC.Core.Configuration.Constants.Guest.ID)
|| (user = UserManager.GetUsers(Id)).Equals(Constants.LostUser)
? string.IsNullOrEmpty(_name)
? FilesCommonResource.Guest
: _name
: user.DisplayUserName(false, DisplayUserSettingsHelper);
}
set { _name = value; }
}
private UserManager UserManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
}
[DebuggerDisplay("{Author.Name}")]
public class EditHistoryChanges
{
public EditHistoryAuthor Author { get; set; }
public DateTime Date { get; set; }
}
[DebuggerDisplay("{Version}")]
public class EditHistoryData
{
public string ChangesUrl { get; set; }
public string Key { get; set; }
public EditHistoryUrl Previous { get; set; }
public string Token { get; set; }
public string Url { get; set; }
public int Version { get; set; }
public string FileType { get; set; }
}
[DebuggerDisplay("{Key} - {Url}")]
public class EditHistoryUrl
{
public string Key { get; set; }
public string Url { get; set; }
public string FileType { get; set; }
}
}

View File

@ -1071,12 +1071,15 @@ namespace ASC.Web.Files.Services.WCFService
Key = DocumentServiceHelper.GetDocKey(file),
Url = DocumentServiceConnector.ReplaceCommunityAdress(PathProvider.GetFileStreamUrl(file, doc)),
Version = version,
FileType = GetFileExtensionWithoutDot(FileUtility.GetFileExtension(file.Title))
};
if (fileDao.ContainChanges(file.ID, file.Version))
{
string previouseKey;
string sourceFileUrl;
string previousFileExt;
if (file.Version > 1)
{
var previousFileStable = fileDao.GetFileStable(file.ID, file.Version - 1);
@ -1085,6 +1088,7 @@ namespace ASC.Web.Files.Services.WCFService
sourceFileUrl = PathProvider.GetFileStreamUrl(previousFileStable, doc);
previouseKey = DocumentServiceHelper.GetDocKey(previousFileStable);
previousFileExt = FileUtility.GetFileExtension(previousFileStable.Title);
}
else
{
@ -1105,12 +1109,14 @@ namespace ASC.Web.Files.Services.WCFService
sourceFileUrl = BaseCommonLinkUtility.GetFullAbsolutePath(sourceFileUrl);
previouseKey = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString());
previousFileExt = fileExt;
}
result.Previous = new EditHistoryUrl
{
Key = previouseKey,
Url = DocumentServiceConnector.ReplaceCommunityAdress(sourceFileUrl),
FileType = GetFileExtensionWithoutDot(previousFileExt)
};
result.ChangesUrl = PathProvider.GetFileChangesUrl(file, doc);
}
@ -1118,6 +1124,11 @@ namespace ASC.Web.Files.Services.WCFService
result.Token = DocumentServiceHelper.GetSignature(result);
return result;
string GetFileExtensionWithoutDot(string ext)
{
return ext.Substring(ext.IndexOf('.') + 1);
}
}
public List<EditHistory> RestoreVersion(T fileId, int version, string url = null, string doc = null)

View File

@ -0,0 +1,49 @@

using System.Collections.Generic;
using System.Linq;
using ASC.Api.Core;
using ASC.Core;
using ASC.Web.Core.Users;
namespace ASC.Files.Core.Model
{
public class EditHistoryWrapper
{
public int ID { get; set; }
public string Key { get; set; }
public int Version { get; set; }
public int VersionGroup { get; set; }
public EditHistoryAuthor User { get; set; }
public ApiDateTime Created { get; set; }
public string ChangesHistory { get; set; }
public List<EditHistoryChangesWrapper> Changes { get; set; }
public string ServerVersion { get; set; }
public EditHistoryWrapper(EditHistory editHistory, ApiDateTimeHelper apiDateTimeHelper, UserManager userManager, DisplayUserSettingsHelper displayUserSettingsHelper)
{
ID = editHistory.ID;
Key = editHistory.Key;
Version = editHistory.Version;
VersionGroup = editHistory.VersionGroup;
Changes = editHistory.Changes.Select(r => new EditHistoryChangesWrapper(r, apiDateTimeHelper)).ToList();
ChangesHistory = editHistory.ChangesString;
Created = apiDateTimeHelper.Get(editHistory.ModifiedOn);
User = new EditHistoryAuthor(userManager, displayUserSettingsHelper) { Id = editHistory.ModifiedBy };
ServerVersion = editHistory.ServerVersion;
}
}
public class EditHistoryChangesWrapper
{
public EditHistoryAuthor User { get; set; }
public ApiDateTime Created { get; set; }
public EditHistoryChangesWrapper(EditHistoryChanges historyChanges, ApiDateTimeHelper apiDateTimeHelper)
{
User = historyChanges.Author;
Created = apiDateTimeHelper.Get(historyChanges.Date);
}
}
}

View File

@ -1517,6 +1517,48 @@ namespace ASC.Api.Documents
return FilesControllerHelperInt.LockFile(fileId, model.LockFile);
}
[AllowAnonymous]
[Read("file/{fileId}/edit/history")]
public List<EditHistoryWrapper> GetEditHistory(string fileId, string doc = null)
{
return FilesControllerHelperString.GetEditHistory(fileId, doc);
}
[AllowAnonymous]
[Read("file/{fileId:int}/edit/history")]
public List<EditHistoryWrapper> GetEditHistory(int fileId, string doc = null)
{
return FilesControllerHelperInt.GetEditHistory(fileId, doc);
}
[AllowAnonymous]
[Read("file/{fileId}/edit/diff")]
public EditHistoryData GetEditDiffUrl(string fileId, int version = 0, string doc = null)
{
return FilesControllerHelperString.GetEditDiffUrl(fileId, version, doc);
}
[AllowAnonymous]
[Read("file/{fileId:int}/edit/diff")]
public EditHistoryData GetEditDiffUrl(int fileId, int version = 0, string doc = null)
{
return FilesControllerHelperInt.GetEditDiffUrl(fileId, version, doc);
}
[AllowAnonymous]
[Read("file/{fileId}/restoreversion")]
public List<EditHistoryWrapper> RestoreVersion(string fileId, int version = 0, string url = null, string doc = null)
{
return FilesControllerHelperString.RestoreVersion(fileId, version, url, doc);
}
[AllowAnonymous]
[Read("file/{fileId:int}/restoreversion")]
public List<EditHistoryWrapper> RestoreVersion(int fileId, int version = 0, string url = null, string doc = null)
{
return FilesControllerHelperInt.RestoreVersion(fileId, version, url, doc);
}
[Update("file/{fileId}/comment")]
public object UpdateCommentFromBody(string fileId, [FromBody] UpdateCommentModel model)
{

View File

@ -21,6 +21,7 @@ using ASC.Files.Core;
using ASC.Files.Core.Model;
using ASC.Files.Model;
using ASC.Web.Core.Files;
using ASC.Web.Core.Users;
using ASC.Web.Files.Classes;
using ASC.Web.Files.Core.Entries;
using ASC.Web.Files.Services.DocumentService;
@ -66,6 +67,9 @@ namespace ASC.Files.Helpers
private EncryptionKeyPairHelper EncryptionKeyPairHelper { get; }
private IHttpContextAccessor HttpContextAccessor { get; }
private FileConverter FileConverter { get; }
private ApiDateTimeHelper ApiDateTimeHelper { get; }
private UserManager UserManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private ILog Logger { get; set; }
/// <summary>
@ -94,7 +98,10 @@ namespace ASC.Files.Helpers
SettingsManager settingsManager,
EncryptionKeyPairHelper encryptionKeyPairHelper,
IHttpContextAccessor httpContextAccessor,
FileConverter fileConverter)
FileConverter fileConverter,
ApiDateTimeHelper apiDateTimeHelper,
UserManager userManager,
DisplayUserSettingsHelper displayUserSettingsHelper)
{
ApiContext = context;
FileStorageService = fileStorageService;
@ -115,6 +122,9 @@ namespace ASC.Files.Helpers
DocumentServiceTracker = documentServiceTracker;
SettingsManager = settingsManager;
EncryptionKeyPairHelper = encryptionKeyPairHelper;
ApiDateTimeHelper = apiDateTimeHelper;
UserManager = userManager;
DisplayUserSettingsHelper = displayUserSettingsHelper;
HttpContextAccessor = httpContextAccessor;
FileConverter = fileConverter;
Logger = optionMonitor.Get("ASC.Files");
@ -571,6 +581,23 @@ namespace ASC.Files.Helpers
return FileStorageService.GetPresignedUri(fileId);
}
public List<EditHistoryWrapper> GetEditHistory(T fileId, string doc = null)
{
var result = FileStorageService.GetEditHistory(fileId, doc);
return result.Select(r => new EditHistoryWrapper(r, ApiDateTimeHelper, UserManager, DisplayUserSettingsHelper)).ToList();
}
public EditHistoryData GetEditDiffUrl(T fileId, int version = 0, string doc = null)
{
return FileStorageService.GetEditDiffUrl(fileId, version, doc);
}
public List<EditHistoryWrapper> RestoreVersion(T fileId, int version = 0, string url = null, string doc = null)
{
var result = FileStorageService.RestoreVersion(fileId, version, url, doc);
return result.Select(r => new EditHistoryWrapper(r, ApiDateTimeHelper, UserManager, DisplayUserSettingsHelper)).ToList();
}
public string UpdateComment(T fileId, int version, string comment)
{
return FileStorageService.UpdateComment(fileId, version, comment);