Files: refactoring

This commit is contained in:
pavelbannov 2020-03-05 10:24:50 +03:00
parent ece437cbc0
commit ae9a5003f3
18 changed files with 711 additions and 477 deletions

View File

@ -205,9 +205,9 @@ namespace ASC.Api.Documents
/// <category>Folders</category>
/// <returns>My folder contents</returns>
[Read("@my")]
public FolderContentWrapper GetMyFolder(Guid userIdOrGroupId, FilterType filterType)
public FolderContentWrapper<string> GetMyFolder(Guid userIdOrGroupId, FilterType filterType)
{
return ToFolderContentWrapper(GlobalFolderHelper.FolderMy, userIdOrGroupId, filterType);
return ToFolderContentWrapper(GlobalFolderHelper.GetFolderMy<string>(), userIdOrGroupId, filterType);
}
/// <summary>
@ -219,9 +219,9 @@ namespace ASC.Api.Documents
/// <category>Folders</category>
/// <returns>Projects folder contents</returns>
[Read("@projects")]
public FolderContentWrapper GetProjectsFolder(Guid userIdOrGroupId, FilterType filterType)
public FolderContentWrapper<string> GetProjectsFolder(Guid userIdOrGroupId, FilterType filterType)
{
return ToFolderContentWrapper(GlobalFolderHelper.FolderProjects, userIdOrGroupId, filterType);
return ToFolderContentWrapper(GlobalFolderHelper.GetFolderProjects<string>(), userIdOrGroupId, filterType);
}
@ -234,9 +234,9 @@ namespace ASC.Api.Documents
/// <category>Folders</category>
/// <returns>Common folder contents</returns>
[Read("@common")]
public FolderContentWrapper GetCommonFolder(Guid userIdOrGroupId, FilterType filterType)
public FolderContentWrapper<int> GetCommonFolder(Guid userIdOrGroupId, FilterType filterType)
{
return ToFolderContentWrapper(GlobalFolderHelper.FolderCommon, userIdOrGroupId, filterType);
return ToFolderContentWrapper(GlobalFolderHelper.GetFolderCommon<int>(), userIdOrGroupId, filterType);
}
/// <summary>
@ -248,9 +248,9 @@ namespace ASC.Api.Documents
/// <category>Folders</category>
/// <returns>Shared folder contents</returns>
[Read("@share")]
public FolderContentWrapper GetShareFolder(Guid userIdOrGroupId, FilterType filterType)
public FolderContentWrapper<string> GetShareFolder(Guid userIdOrGroupId, FilterType filterType)
{
return ToFolderContentWrapper(GlobalFolderHelper.FolderShare, userIdOrGroupId, filterType);
return ToFolderContentWrapper(GlobalFolderHelper.GetFolderShare<string>(), userIdOrGroupId, filterType);
}
/// <summary>
@ -262,9 +262,9 @@ namespace ASC.Api.Documents
/// <category>Folders</category>
/// <returns>Trash folder contents</returns>
[Read("@trash")]
public FolderContentWrapper GetTrashFolder(Guid userIdOrGroupId, FilterType filterType)
public FolderContentWrapper<string> GetTrashFolder(Guid userIdOrGroupId, FilterType filterType)
{
return ToFolderContentWrapper(GlobalFolderHelper.FolderTrash, userIdOrGroupId, filterType);
return ToFolderContentWrapper(GlobalFolderHelper.GetFolderTrash<string>(), userIdOrGroupId, filterType);
}
/// <summary>
@ -279,13 +279,13 @@ namespace ASC.Api.Documents
/// <param name="filterType" optional="true" remark="Allowed values: None (0), FilesOnly (1), FoldersOnly (2), DocumentsOnly (3), PresentationsOnly (4), SpreadsheetsOnly (5) or ImagesOnly (7)">Filter type</param>
/// <returns>Folder contents</returns>
[Read("{folderId}", order: int.MaxValue)]
public FolderContentWrapper GetFolder(string folderId, Guid userIdOrGroupId, FilterType filterType)
public FolderContentWrapper<string> GetFolder(string folderId, Guid userIdOrGroupId, FilterType filterType)
{
return ToFolderContentWrapper(folderId, userIdOrGroupId, filterType).NotFoundIfNull();
}
[Read("{folderId:int}", order: int.MaxValue)]
public FolderContentWrapper GetFolder(int folderId, Guid userIdOrGroupId, FilterType filterType)
public FolderContentWrapper<int> GetFolder(int folderId, Guid userIdOrGroupId, FilterType filterType)
{
return ToFolderContentWrapper(folderId, userIdOrGroupId, filterType).NotFoundIfNull();
}
@ -405,7 +405,7 @@ namespace ASC.Api.Documents
/// <category>Uploads</category>
/// <returns></returns>
[Create("@my/insert")]
public FileWrapper InsertFileToMy(Stream file, string title, bool? createNewIfExist, bool keepConvertStatus = false)
public FileWrapper<string> InsertFileToMy(Stream file, string title, bool? createNewIfExist, bool keepConvertStatus = false)
{
return InsertFile(GlobalFolderHelper.FolderMy.ToString(), file, title, createNewIfExist, keepConvertStatus);
}
@ -420,7 +420,7 @@ namespace ASC.Api.Documents
/// <category>Uploads</category>
/// <returns></returns>
[Create("@common/insert")]
public FileWrapper InsertFileToCommon(Stream file, string title, bool? createNewIfExist, bool keepConvertStatus = false)
public FileWrapper<string> InsertFileToCommon(Stream file, string title, bool? createNewIfExist, bool keepConvertStatus = false)
{
return InsertFile(GlobalFolderHelper.FolderCommon.ToString(), file, title, createNewIfExist, keepConvertStatus);
}
@ -436,7 +436,7 @@ namespace ASC.Api.Documents
/// <category>Uploads</category>
/// <returns></returns>
[Create("{folderId}/insert")]
public FileWrapper InsertFile(string folderId, Stream file, string title, bool? createNewIfExist, bool keepConvertStatus = false)
public FileWrapper<string> InsertFile(string folderId, Stream file, string title, bool? createNewIfExist, bool keepConvertStatus = false)
{
try
{
@ -462,7 +462,7 @@ namespace ASC.Api.Documents
/// <returns></returns>
/// <visible>false</visible>
[Update("{fileId}/update")]
public FileWrapper UpdateFileStream(Stream file, string fileId, bool encrypted = false)
public FileWrapper<string> UpdateFileStream(Stream file, string fileId, bool encrypted = false)
{
try
{
@ -488,7 +488,7 @@ namespace ASC.Api.Documents
/// <category>Files</category>
/// <returns></returns>
[Update("file/{fileId}/saveediting")]
public FileWrapper SaveEditing(string fileId, string fileExtension, string downloadUri, Stream stream, string doc, bool forcesave)
public FileWrapper<string> SaveEditing(string fileId, string fileExtension, string downloadUri, Stream stream, string doc, bool forcesave)
{
return FileWrapperHelper.Get(FileStorageService.SaveEditing(fileId, fileExtension, downloadUri, stream, doc, forcesave));
}
@ -624,7 +624,7 @@ namespace ASC.Api.Documents
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("@my/text")]
public FileWrapper CreateTextFileInMy(string title, string content)
public FileWrapper<string> CreateTextFileInMy(string title, string content)
{
return CreateTextFile(GlobalFolderHelper.FolderMy.ToString(), title, content);
}
@ -638,7 +638,7 @@ namespace ASC.Api.Documents
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("@common/text")]
public FileWrapper CreateTextFileInCommon(string title, string content)
public FileWrapper<string> CreateTextFileInCommon(string title, string content)
{
return CreateTextFile(GlobalFolderHelper.FolderCommon.ToString(), title, content);
}
@ -653,7 +653,7 @@ namespace ASC.Api.Documents
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("{folderId}/text")]
public FileWrapper CreateTextFile(string folderId, string title, string content)
public FileWrapper<string> CreateTextFile(string folderId, string title, string content)
{
if (title == null) throw new ArgumentNullException("title");
//Try detect content
@ -668,11 +668,11 @@ namespace ASC.Api.Documents
return CreateFile(folderId, title, content, extension);
}
private FileWrapper CreateFile<T>(T folderId, string title, string content, string extension)
private FileWrapper<T> CreateFile<T>(T folderId, string title, string content, string extension)
{
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
var file = FileUploader.Exec(folderId.ToString(),
var file = FileUploader.Exec(folderId,
title.EndsWith(extension, StringComparison.OrdinalIgnoreCase) ? title : (title + extension),
memStream.Length, memStream);
return FileWrapperHelper.Get(file);
@ -689,7 +689,7 @@ namespace ASC.Api.Documents
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("{folderId}/html")]
public FileWrapper CreateHtmlFile(string folderId, string title, string content)
public FileWrapper<string> CreateHtmlFile(string folderId, string title, string content)
{
if (title == null) throw new ArgumentNullException("title");
return CreateFile(folderId, title, content, ".html");
@ -704,7 +704,7 @@ namespace ASC.Api.Documents
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("@my/html")]
public FileWrapper CreateHtmlFileInMy(string title, string content)
public FileWrapper<string> CreateHtmlFileInMy(string title, string content)
{
return CreateHtmlFile(GlobalFolderHelper.FolderMy.ToString(), title, content);
}
@ -719,7 +719,7 @@ namespace ASC.Api.Documents
/// <param name="content">File contents</param>
/// <returns>Folder contents</returns>
[Create("@common/html")]
public FileWrapper CreateHtmlFileInCommon(string title, string content)
public FileWrapper<string> CreateHtmlFileInCommon(string title, string content)
{
return CreateHtmlFile(GlobalFolderHelper.FolderCommon.ToString(), title, content);
}
@ -736,7 +736,7 @@ namespace ASC.Api.Documents
/// <param name="title">Title of new folder</param>
/// <returns>New folder contents</returns>
[Create("folder/{folderId}")]
public FolderWrapper CreateFolder(string folderId, string title)
public FolderWrapper<string> CreateFolder(string folderId, string title)
{
var folder = FileStorageService.CreateNewFolder(folderId, title);
return FolderWrapperHelper.Get(folder);
@ -751,7 +751,7 @@ namespace ASC.Api.Documents
/// <remarks>In case the extension for the file title differs from DOCX/XLSX/PPTX and belongs to one of the known text, spreadsheet or presentation formats, it will be changed to DOCX/XLSX/PPTX accordingly. If the file extension is not set or is unknown, the DOCX extension will be added to the file title.</remarks>
/// <returns>New file info</returns>
[Create("@my/file")]
public FileWrapper CreateFile(string title)
public FileWrapper<string> CreateFile(string title)
{
return CreateFile(GlobalFolderHelper.FolderMy.ToString(), title);
}
@ -766,7 +766,7 @@ namespace ASC.Api.Documents
/// <remarks>In case the extension for the file title differs from DOCX/XLSX/PPTX and belongs to one of the known text, spreadsheet or presentation formats, it will be changed to DOCX/XLSX/PPTX accordingly. If the file extension is not set or is unknown, the DOCX extension will be added to the file title.</remarks>
/// <returns>New file info</returns>
[Create("{folderId}/file")]
public FileWrapper CreateFile(string folderId, string title)
public FileWrapper<string> CreateFile(string folderId, string title)
{
var file = FileStorageService.CreateNewFile(new FileModel<string> { ParentId = folderId, Title = title });
return FileWrapperHelper.Get(file);
@ -783,7 +783,7 @@ namespace ASC.Api.Documents
/// <param name="title">New title</param>
/// <returns>Folder contents</returns>
[Update("folder/{folderId}")]
public FolderWrapper RenameFolder(string folderId, string title)
public FolderWrapper<string> RenameFolder(string folderId, string title)
{
var folder = FileStorageService.FolderRename(folderId, title);
return FolderWrapperHelper.Get(folder);
@ -796,7 +796,7 @@ namespace ASC.Api.Documents
/// <category>Folders</category>
/// <returns>Folder info</returns>
[Read("folder/{folderId}")]
public FolderWrapper GetFolderInfo(string folderId)
public FolderWrapper<string> GetFolderInfo(string folderId)
{
var folder = FileStorageService.GetFolder(folderId).NotFoundIfNull("Folder not found");
@ -810,7 +810,7 @@ namespace ASC.Api.Documents
/// <category>Folders</category>
/// <returns>Parent folders</returns>
[Read("folder/{folderId}/path")]
public IEnumerable<FolderWrapper> GetFolderPath(string folderId)
public IEnumerable<FolderWrapper<string>> GetFolderPath(string folderId)
{
return EntryManager.GetBreadCrumbs(folderId).Select(FolderWrapperHelper.Get);
}
@ -822,7 +822,7 @@ namespace ASC.Api.Documents
/// <category>Files</category>
/// <returns>File info</returns>
[Read("file/{fileId}")]
public FileWrapper GetFileInfo(string fileId, int version = -1)
public FileWrapper<string> GetFileInfo(string fileId, int version = -1)
{
var file = FileStorageService.GetFile(fileId, version).NotFoundIfNull("File not found");
return FileWrapperHelper.Get(file);
@ -835,7 +835,7 @@ namespace ASC.Api.Documents
/// <category>Files</category>
/// <returns>File info</returns>
[Read("file/{fileId:int}")]
public FileWrapper GetFileInfo(int fileId, int version = -1)
public FileWrapper<int> GetFileInfo(int fileId, int version = -1)
{
var file = FileStorageServiceInt.GetFile(fileId, version).NotFoundIfNull("File not found");
return FileWrapperHelper.Get(file);
@ -851,7 +851,7 @@ namespace ASC.Api.Documents
/// <param name="lastVersion">File last version number</param>
/// <returns>File info</returns>
[Update("file/{fileId}")]
public FileWrapper UpdateFile(string fileId, string title, int lastVersion)
public FileWrapper<string> UpdateFile(string fileId, string title, int lastVersion)
{
if (!string.IsNullOrEmpty(title))
FileStorageService.FileRename(fileId.ToString(CultureInfo.InvariantCulture), title);
@ -872,7 +872,7 @@ namespace ASC.Api.Documents
/// <param name="immediately">Don't move to the Recycle Bin</param>
/// <returns>Operation result</returns>
[Delete("file/{fileId}")]
public IEnumerable<FileOperationWraper> DeleteFile(string fileId, bool deleteAfter, bool immediately)
public IEnumerable<FileOperationWraper<string>> DeleteFile(string fileId, bool deleteAfter, bool immediately)
{
var model = new DeleteBatchModel
{
@ -942,7 +942,7 @@ namespace ASC.Api.Documents
/// <param name="immediately">Don't move to the Recycle Bin</param>
/// <returns>Operation result</returns>
[Delete("folder/{folderId}")]
public IEnumerable<FileOperationWraper> DeleteFolder(string folderId, bool deleteAfter, bool immediately)
public IEnumerable<FileOperationWraper<string>> DeleteFolder(string folderId, bool deleteAfter, bool immediately)
{
var model = new DeleteBatchModel
{
@ -963,7 +963,7 @@ namespace ASC.Api.Documents
/// <param name="fileIds">File ID list</param>
/// <returns>Conflicts file ids</returns>
[Read("fileops/move")]
public IEnumerable<FileWrapper> MoveOrCopyBatchCheck(BatchModel batchModel)
public IEnumerable<FileWrapper<string>> MoveOrCopyBatchCheck(BatchModel batchModel)
{
var itemList = new ItemList<string>();
@ -988,7 +988,7 @@ namespace ASC.Api.Documents
/// <param name="deleteAfter">Delete after finished</param>
/// <returns>Operation result</returns>
[Update("fileops/move")]
public IEnumerable<FileOperationWraper> MoveBatchItems(BatchModel batchModel)
public IEnumerable<FileOperationWraper<string>> MoveBatchItems(BatchModel batchModel)
{
var itemList = new ItemList<string>();
@ -1010,7 +1010,7 @@ namespace ASC.Api.Documents
/// <param name="deleteAfter">Delete after finished</param>
/// <returns>Operation result</returns>
[Update("fileops/copy")]
public IEnumerable<FileOperationWraper> CopyBatchItems(BatchModel batchModel)
public IEnumerable<FileOperationWraper<string>> CopyBatchItems(BatchModel batchModel)
{
var itemList = new ItemList<string>();
@ -1027,7 +1027,7 @@ namespace ASC.Api.Documents
/// <category>File operations</category>
/// <returns>Operation result</returns>
[Update("fileops/markasread")]
public IEnumerable<FileOperationWraper> MarkAsRead(BaseBatchModel model)
public IEnumerable<FileOperationWraper<string>> MarkAsRead(BaseBatchModel model)
{
var itemList = new ItemList<string>();
@ -1044,7 +1044,7 @@ namespace ASC.Api.Documents
/// <category>File operations</category>
/// <returns>Operation result</returns>
[Update("fileops/terminate")]
public IEnumerable<FileOperationWraper> TerminateTasks()
public IEnumerable<FileOperationWraper<string>> TerminateTasks()
{
return FileStorageService.TerminateTasks().Select(FileOperationWraperHelper.Get<string>);
}
@ -1057,7 +1057,7 @@ namespace ASC.Api.Documents
/// <category>File operations</category>
/// <returns>Operation result</returns>
[Read("fileops")]
public IEnumerable<FileOperationWraper> GetOperationStatuses()
public IEnumerable<FileOperationWraper<string>> GetOperationStatuses()
{
return FileStorageService.GetTasksStatuses().Select(FileOperationWraperHelper.Get<string>);
}
@ -1072,7 +1072,7 @@ namespace ASC.Api.Documents
/// <category>File operations</category>
/// <returns>Operation result</returns>
[Update("fileops/bulkdownload")]
public IEnumerable<FileOperationWraper> BulkDownload(DownloadModel model)
public IEnumerable<FileOperationWraper<string>> BulkDownload(DownloadModel model)
{
var itemList = new Dictionary<string, string>();
@ -1105,7 +1105,7 @@ namespace ASC.Api.Documents
/// <category>File operations</category>
/// <returns>Operation result</returns>
[Update("fileops/delete")]
public IEnumerable<FileOperationWraper> DeleteBatchItems(DeleteBatchModel batch)
public IEnumerable<FileOperationWraper<string>> DeleteBatchItems(DeleteBatchModel batch)
{
var itemList = new ItemList<string>();
@ -1122,7 +1122,7 @@ namespace ASC.Api.Documents
/// <category>File operations</category>
/// <returns>Operation result</returns>
[Update("fileops/emptytrash")]
public IEnumerable<FileOperationWraper> EmptyTrash()
public IEnumerable<FileOperationWraper<string>> EmptyTrash()
{
return FileStorageService.EmptyTrash().Select(FileOperationWraperHelper.Get<string>);
}
@ -1135,7 +1135,7 @@ namespace ASC.Api.Documents
/// <param name="fileId">File ID</param>
/// <returns>File information</returns>
[Read("file/{fileId}/history")]
public IEnumerable<FileWrapper> GetFileVersionInfo(string fileId)
public IEnumerable<FileWrapper<string>> GetFileVersionInfo(string fileId)
{
var files = FileStorageService.GetFileHistory(fileId);
return files.Select(FileWrapperHelper.Get);
@ -1150,7 +1150,7 @@ namespace ASC.Api.Documents
/// <category>Files</category>
/// <returns></returns>
[Update("file/{fileId}/history")]
public IEnumerable<FileWrapper> ChangeHistory(string fileId, int version, bool continueVersion)
public IEnumerable<FileWrapper<string>> ChangeHistory(string fileId, int version, bool continueVersion)
{
var history = FileStorageService.CompleteVersion(fileId, version, continueVersion).Value;
return history.Select(FileWrapperHelper.Get);
@ -1378,7 +1378,7 @@ namespace ASC.Api.Documents
/// <remarks>List of provider key: DropboxV2, Box, WebDav, Yandex, OneDrive, SharePoint, GoogleDrive</remarks>
/// <exception cref="ArgumentException"></exception>
[Create("thirdparty")]
public FolderWrapper SaveThirdParty(
public FolderWrapper<string> SaveThirdParty(
string url,
string login,
string password,
@ -1547,7 +1547,7 @@ namespace ASC.Api.Documents
}
private FolderContentWrapper ToFolderContentWrapper(object folderId, Guid userIdOrGroupId, FilterType filterType)
private FolderContentWrapper<string> ToFolderContentWrapper(string folderId, Guid userIdOrGroupId, FilterType filterType)
{
if (!Enum.TryParse(ApiContext.SortBy, true, out SortedByType sortBy))
{
@ -1568,7 +1568,7 @@ namespace ASC.Api.Documents
startIndex);
}
private FolderContentWrapper ToFolderContentWrapper(int folderId, Guid userIdOrGroupId, FilterType filterType)
private FolderContentWrapper<int> ToFolderContentWrapper(int folderId, Guid userIdOrGroupId, FilterType filterType)
{
if (!Enum.TryParse(ApiContext.SortBy, true, out SortedByType sortBy))
{
@ -1823,7 +1823,7 @@ namespace ASC.Api.Documents
/// Result file of operation.
/// </summary>
[DataMember(Name = "result")]
public FileWrapper File { get; set; }
public FileWrapper<string> File { get; set; }
/// <summary>
/// Error during conversation.

View File

@ -58,7 +58,7 @@ namespace ASC.Files.Core.Data
public GlobalStore GlobalStore { get; }
public GlobalSpace GlobalSpace { get; }
public GlobalFolder GlobalFolder { get; }
public IFolderDao<int> FolderDao { get; }
public IDaoFactory DaoFactory { get; }
public ChunkedUploadSessionHolder ChunkedUploadSessionHolder { get; }
public FileDao(
@ -78,7 +78,7 @@ namespace ASC.Files.Core.Data
GlobalStore globalStore,
GlobalSpace globalSpace,
GlobalFolder globalFolder,
IFolderDao<int> folderDao,
IDaoFactory daoFactory,
ChunkedUploadSessionHolder chunkedUploadSessionHolder)
: base(
dbContextManager,
@ -98,7 +98,7 @@ namespace ASC.Files.Core.Data
GlobalStore = globalStore;
GlobalSpace = globalSpace;
GlobalFolder = globalFolder;
FolderDao = folderDao;
DaoFactory = daoFactory;
ChunkedUploadSessionHolder = chunkedUploadSessionHolder;
}
@ -687,7 +687,7 @@ namespace ASC.Files.Core.Data
{
f.FolderId = toFolderId;
if (GlobalFolder.GetFolderTrash<int>(FolderDao).Equals(toFolderId))
if (GlobalFolder.GetFolderTrash<int>(DaoFactory).Equals(toFolderId))
{
f.ModifiedBy = AuthContext.CurrentAccount.ID;
f.ModifiedOn = DateTime.UtcNow;

View File

@ -416,7 +416,191 @@ namespace ASC.Files.Core.Data
public IEnumerable<Tag> GetNewTags(Guid subject, Folder<int> parentFolder, bool deepSearch)
{
throw new NotImplementedException();
if (parentFolder == null || parentFolder.ID == 0)
throw new ArgumentException("folderId");
var result = new List<Tag>();
var monitorFolderIds = new object[] { parentFolder.ID }.AsEnumerable();
var getBaseSqlQuery = new Func<IQueryable<TagLinkData>>(() =>
{
var fnResult = Query(FilesDbContext.Tag)
.Join(FilesDbContext.TagLink, r => r.Id, l => l.TagId, (tag, link) => new TagLinkData { Tag = tag, Link = link })
.Where(r => r.Link.TenantId == r.Tag.TenantId)
.Where(r => r.Tag.Flag == TagType.New)
.Distinct();
if (subject != Guid.Empty)
{
fnResult = fnResult.Where(r => r.Tag.Owner == subject);
}
return fnResult;
});
var tempTags = Enumerable.Empty<Tag>();
if (parentFolder.FolderType == FolderType.SHARE)
{
var shareQuery =
new Func<IQueryable<TagLinkData>>(() => getBaseSqlQuery().Where(
r => FilesDbContext.Security
.Where(a => a.TenantId == r.Link.TenantId)
.Where(a => a.EntryId == r.Link.EntryId)
.Where(a => a.EntryType == r.Link.EntryType)
.Any()));
var tmpShareFileTags =
shareQuery()
.Join(FilesDbContext.Files, r => r.Link.EntryId, f => f.Id.ToString(), (tagLink, file) => new { tagLink, file })
.Where(r => r.file.TenantId == r.tagLink.Link.TenantId)
.Where(r => r.file.CreateBy != subject)
.Where(r => r.tagLink.Link.EntryType == FileEntryType.File)
.Select(r => new
{
r.tagLink,
root = FilesDbContext.Folders
.Join(FilesDbContext.Tree, a => a.Id, b => b.ParentId, (folder, tree) => new { folder, tree })
.Where(x => x.folder.TenantId == r.file.TenantId)
.Where(x => x.tree.FolderId == r.file.FolderId)
.OrderByDescending(r => r.tree.Level)
.Select(r => r.folder)
.FirstOrDefault()
})
.Where(r => r.root.FolderType == FolderType.USER)
.Select(r => r.tagLink);
tempTags = tempTags.Concat(FromQuery(tmpShareFileTags));
var tmpShareFolderTags =
shareQuery()
.Join(FilesDbContext.Folders, r => r.Link.EntryId, f => f.Id.ToString(), (tagLink, folder) => new { tagLink, folder })
.Where(r => r.folder.TenantId == r.tagLink.Link.TenantId)
.Where(r => r.folder.CreateBy != subject)
.Where(r => r.tagLink.Link.EntryType == FileEntryType.Folder)
.Select(r => new
{
r.tagLink,
root = FilesDbContext.Folders
.Join(FilesDbContext.Tree, a => a.Id, b => b.ParentId, (folder, tree) => new { folder, tree })
.Where(x => x.folder.TenantId == r.folder.TenantId)
.Where(x => x.tree.FolderId == r.folder.ParentId)
.OrderByDescending(r => r.tree.Level)
.Select(r => r.folder)
.FirstOrDefault()
})
.Where(r => r.root.FolderType == FolderType.USER)
.Select(r => r.tagLink);
tempTags = tempTags.Concat(FromQuery(tmpShareFolderTags));
var tmpShareSboxTags =
shareQuery()
.Join(FilesDbContext.ThirdpartyIdMapping, r => r.Link.EntryId, r => r.HashId, (tagLink, mapping) => new { tagLink, mapping })
.Where(r => r.mapping.TenantId == r.tagLink.Link.TenantId)
.Join(FilesDbContext.ThirdpartyAccount, r => r.mapping.TenantId, r => r.TenantId, (tagLinkMapping, account) => new { tagLinkMapping.tagLink, tagLinkMapping.mapping, account })
.Where(r => r.account.UserId != subject)
.Where(r => r.account.FolderType == FolderType.USER)
.Where(r =>
r.mapping.Id.StartsWith("sbox-" + r.account.Id) ||
r.mapping.Id.StartsWith("box-" + r.account.Id) ||
r.mapping.Id.StartsWith("dropbox-" + r.account.Id) ||
r.mapping.Id.StartsWith("spoint-" + r.account.Id) ||
r.mapping.Id.StartsWith("drive-" + r.account.Id) ||
r.mapping.Id.StartsWith("onedrive-" + r.account.Id)
)
.Select(r => r.tagLink);
tempTags = tempTags.Concat(FromQuery(tmpShareSboxTags));
}
else if (parentFolder.FolderType == FolderType.Projects)
{
var q = getBaseSqlQuery()
.Join(FilesDbContext.BunchObjects, r => r.Link.TenantId, r => r.TenantId, (tagLink, bunch) => new { tagLink, bunch })
.Where(r => r.bunch.LeftNode == r.tagLink.Link.EntryId)
.Where(r => r.tagLink.Link.EntryType == FileEntryType.Folder)
.Where(r => r.bunch.RightNode.StartsWith("projects/project/"))
.Select(r => r.tagLink);
tempTags = tempTags.Concat(FromQuery(q));
}
if (tempTags.Any())
{
if (!deepSearch) return tempTags;
monitorFolderIds = monitorFolderIds.Concat(tempTags.Where(x => x.EntryType == FileEntryType.Folder).Select(x => x.EntryId));
result.AddRange(tempTags);
}
var monitorFolderIdsInt = monitorFolderIds.Select(r => Convert.ToInt32(r)).ToList();
var subFoldersSqlQuery =
FilesDbContext.Tree
.Where(r => monitorFolderIdsInt.Any(a => r.ParentId == a));
if (!deepSearch)
{
subFoldersSqlQuery = subFoldersSqlQuery.Where(r => r.Level == 1);
}
monitorFolderIds = monitorFolderIds.Concat(subFoldersSqlQuery.Select(r => r.FolderId).ToList().ConvertAll(r => (object)r));
var monitorFolderIdsStrings = monitorFolderIds.Select(r => r.ToString()).ToList();
var newTagsForFolders = getBaseSqlQuery()
.Where(r => monitorFolderIdsStrings.Any(a => r.Link.EntryId == a))
.Where(r => r.Link.EntryType == FileEntryType.Folder);
result.AddRange(FromQuery(newTagsForFolders));
var where = (deepSearch ? monitorFolderIds.ToArray() : new object[] { parentFolder.ID })
.Select(r => r.ToString())
.ToList();
var newTagsForFiles =
getBaseSqlQuery()
.Join(FilesDbContext.Files, r => r.Link.EntryId, r => r.Id.ToString(), (tagLink, file) => new { tagLink, file })
.Where(r => r.file.TenantId == r.tagLink.Link.TenantId)
.Where(r => where.Any(a => r.file.FolderId.ToString() == a))
.Where(r => r.tagLink.Link.EntryType == FileEntryType.File)
.Select(r => r.tagLink);
result.AddRange(FromQuery(newTagsForFiles));
if (parentFolder.FolderType == FolderType.USER || parentFolder.FolderType == FolderType.COMMON)
{
var folderType = parentFolder.FolderType;
var querySelect = FilesDbContext.ThirdpartyAccount
.Where(r => r.TenantId == TenantID)
.Where(r => r.FolderType == folderType);
if (folderType == FolderType.USER)
{
querySelect = querySelect.Where(r => r.UserId == subject);
}
var folderIds = querySelect.Select(r => r.Id).ToList();
var thirdpartyFolderIds = folderIds.ConvertAll(r => "sbox-" + r)
.Concat(folderIds.ConvertAll(r => $"box-{r}"))
.Concat(folderIds.ConvertAll(r => $"dropbox-{r}"))
.Concat(folderIds.ConvertAll(r => $"spoint-{r}"))
.Concat(folderIds.ConvertAll(r => $"drive-{r}"))
.Concat(folderIds.ConvertAll(r => $"onedrive-{r}"));
var newTagsForSBox = getBaseSqlQuery()
.Join(FilesDbContext.ThirdpartyIdMapping, r => r.Link.EntryId, r => r.HashId, (tagLink, mapping) => new { tagLink, mapping })
.Where(r => r.mapping.TenantId == r.tagLink.Link.TenantId)
.Where(r => thirdpartyFolderIds.Any(a => r.mapping.Id == a))
.Where(r => r.tagLink.Tag.Owner == subject)
.Where(r => r.tagLink.Link.EntryType == FileEntryType.Folder)
.Select(r => r.tagLink);
result.AddRange(FromQuery(newTagsForSBox));
}
return result;
}
protected List<Tag> FromQuery(IQueryable<TagLinkData> dbFilesTags)
@ -429,7 +613,7 @@ namespace ASC.Files.Core.Data
private Tag ToTag(TagLinkData r)
{
var result = new Tag(r.Tag.Name, r.Tag.Flag, r.Tag.Owner, null, r.Link.TagCount)
var result = new Tag(r.Tag.Name, r.Tag.Flag, r.Tag.Owner, r.Link.TagCount)
{
EntryId = MappingID(r.Link.EntryId),
EntryType = r.Link.EntryType,

View File

@ -60,23 +60,28 @@ namespace ASC.Files.Core
}
public Tag(string name, TagType type, Guid owner)
: this(name, type, owner, null, 0)
: this(name, type, owner, 0)
{
}
public Tag(string name, TagType type, Guid owner, FileEntry entry, int count)
public Tag(string name, TagType type, Guid owner, int count)
{
TagName = name;
TagType = type;
Owner = owner;
Count = count;
}
public Tag AddEntry<T>(FileEntry<T> entry)
{
if (entry != null)
{
EntryId = entry.ID;
EntryType = entry.FileEntryType;
}
}
return this;
}
public static Tag New<T>(Guid owner, FileEntry<T> entry)
{
@ -85,13 +90,17 @@ namespace ASC.Files.Core
public static Tag New<T>(Guid owner, FileEntry<T> entry, int count)
{
return new Tag("new", TagType.New, owner, entry, count);
return new Tag("new", TagType.New, owner, count).AddEntry(entry);
}
public override bool Equals(object obj)
{
var f = obj as Tag;
return f != null && f.Id == Id && f.EntryType == EntryType && Equals(f.EntryId, EntryId);
return f != null && Equals(f);
}
public bool Equals(Tag f)
{
return f.Id == Id && f.EntryType == EntryType && Equals(f.EntryId, EntryId);
}
public override int GetHashCode()

View File

@ -315,7 +315,7 @@ namespace ASC.Web.Files.Services.WCFService
var folderItems = GetFolderItems(parentId, from, count, filter, subjectGroup, subjectID, search, searchInContent, withSubfolders, orderBy);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(serializer.ToXml<T>(folderItems))
Content = new StreamContent(serializer.ToXml(folderItems))
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
return response;
@ -854,7 +854,7 @@ namespace ASC.Web.Files.Services.WCFService
{
if (tagLocked == null)
{
tagLocked = new Tag("locked", TagType.Locked, AuthContext.CurrentAccount.ID, file, 0);
tagLocked = new Tag("locked", TagType.Locked, AuthContext.CurrentAccount.ID, 0).AddEntry<T>(file);
tagDao.SaveTags(tagLocked);
}
@ -1046,7 +1046,7 @@ namespace ASC.Web.Files.Services.WCFService
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(serializer.ToXml<T>(new ItemList<FileEntry<T>>(result)))
Content = new StreamContent(serializer.ToXml(new ItemList<FileEntry<T>>(result)))
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
return response;
@ -1157,7 +1157,7 @@ namespace ASC.Web.Files.Services.WCFService
lostFolderType = lostProvider.RootFolderType;
if (lostProvider.RootFolderType == FolderType.COMMON && !thirdPartyParams.Corporate)
{
var lostFolder = folderDao.GetFolder((int)lostProvider.RootFolderId);
var lostFolder = folderDao.GetFolder((T)Convert.ChangeType(lostProvider.RootFolderId, typeof(T)));
FileMarker.RemoveMarkAsNewForAll(lostFolder);
}

View File

@ -511,6 +511,7 @@ namespace ASC.Web.Files.Classes
public T GetFolderMy<T>() => (T)Convert.ChangeType(FolderMy, typeof(T));
public T GetFolderCommon<T>() => (T)Convert.ChangeType(FolderCommon, typeof(T));
public T GetFolderProjects<T>() => (T)Convert.ChangeType(FolderProjects, typeof(T));
public T GetFolderTrash<T>() => (T)Convert.ChangeType(FolderTrash, typeof(T));
public void SetFolderMy<T>(T val)
{

View File

@ -1000,7 +1000,7 @@ namespace ASC.Web.Files
return;
}
FileMarker.MarkAsNew<T>(file);
FileMarker.MarkAsNew(file);
if (responseMessage)
{

View File

@ -37,12 +37,12 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
[DataContract(Namespace = "")]
public abstract class FileEntryWrapper
public abstract class FileEntryWrapper<T>
{
/// <summary>
/// </summary>
[DataMember]
public object Id { get; set; }
public T Id { get; set; }
/// <summary>
/// </summary>
@ -152,7 +152,7 @@ namespace ASC.Api.Documents
EmployeeWraperHelper = employeeWraperHelper;
}
protected internal T Get<T>(FileEntry<T> entry) where T : FileEntryWrapper, new()
protected internal T Get<T, TId>(FileEntry<TId> entry) where T : FileEntryWrapper<TId>, new()
{
return new T
{

View File

@ -40,7 +40,7 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
[DataContract(Name = "operation_result", Namespace = "")]
public class FileOperationWraper
public class FileOperationWraper<T>
{
/// <summary>
/// </summary>
@ -80,12 +80,12 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
[DataMember(Name = "files", IsRequired = true, EmitDefaultValue = true)]
public List<FileWrapper> Files { get; set; }
public List<FileWrapper<T>> Files { get; set; }
/// <summary>
/// </summary>
[DataMember(Name = "folders", IsRequired = true, EmitDefaultValue = true)]
public List<FolderWrapper> Folders { get; set; }
public List<FolderWrapper<T>> Folders { get; set; }
/// <summary>
/// </summary>
@ -96,9 +96,9 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
/// <returns></returns>
public static FileOperationWraper GetSample()
public static FileOperationWraper<int> GetSample()
{
return new FileOperationWraper
return new FileOperationWraper<int>
{
Id = Guid.NewGuid().ToString(),
OperationType = FileOperationType.Move,
@ -107,8 +107,8 @@ namespace ASC.Api.Documents
//Result = "folder_1,file_1",
Error = "",
Processed = "1",
Files = new List<FileWrapper> { FileWrapper.GetSample() },
Folders = new List<FolderWrapper> { FolderWrapper.GetSample() }
Files = new List<FileWrapper<int>> { FileWrapper<int>.GetSample() },
Folders = new List<FolderWrapper<int>> { FolderWrapper<int>.GetSample() }
};
}
}
@ -132,9 +132,9 @@ namespace ASC.Api.Documents
CommonLinkUtility = commonLinkUtility;
}
public FileOperationWraper Get<T>(FileOperationResult o)
public FileOperationWraper<T> Get<T>(FileOperationResult o)
{
var result = new FileOperationWraper
var result = new FileOperationWraper<T>
{
Id = o.Id,
OperationType = o.OperationType,

View File

@ -46,12 +46,12 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
[DataContract(Name = "file", Namespace = "")]
public class FileWrapper : FileEntryWrapper
public class FileWrapper<T> : FileEntryWrapper<T>
{
/// <summary>
/// </summary>
[DataMember(EmitDefaultValue = false, IsRequired = false)]
public object FolderId { get; set; }
public T FolderId { get; set; }
/// <summary>
/// </summary>
@ -120,9 +120,9 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
/// <returns></returns>
public static FileWrapper GetSample()
public static FileWrapper<int> GetSample()
{
return new FileWrapper
return new FileWrapper<int>
{
Access = FileShare.ReadWrite,
//Updated = ApiDateTime.GetSample(),
@ -175,9 +175,9 @@ namespace ASC.Api.Documents
FileUtility = fileUtility;
}
public FileWrapper Get<T>(File<T> file)
public FileWrapper<T> Get<T>(File<T> file)
{
var result = Get<FileWrapper>(file);
var result = Get<FileWrapper<T>, T>(file);
result.FolderId = file.FolderID;
if (file.RootFolderType == FolderType.USER
&& !Equals(file.RootFolderCreator, AuthContext.CurrentAccount.ID))
@ -187,7 +187,7 @@ namespace ASC.Api.Documents
var parentFolder = folderDao.GetFolder(file.FolderID);
if (!FileSecurity.CanRead(parentFolder))
{
result.FolderId = GlobalFolderHelper.FolderShare;
result.FolderId = GlobalFolderHelper.GetFolderShare<T>();
}
}

View File

@ -37,22 +37,22 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
[DataContract(Name = "content", Namespace = "")]
public class FolderContentWrapper
public class FolderContentWrapper<T>
{
/// <summary>
/// </summary>
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public List<FileWrapper> Files { get; set; }
public List<FileWrapper<T>> Files { get; set; }
/// <summary>
/// </summary>
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public List<FolderWrapper> Folders { get; set; }
public List<FolderWrapper<T>> Folders { get; set; }
/// <summary>
/// </summary>
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public FolderWrapper Current { get; set; }
public FolderWrapper<T> Current { get; set; }
/// <summary>
/// </summary>
@ -86,13 +86,13 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
/// <returns></returns>
public static FolderContentWrapper GetSample()
public static FolderContentWrapper<int> GetSample()
{
return new FolderContentWrapper
return new FolderContentWrapper<int>
{
Current = FolderWrapper.GetSample(),
Files = new List<FileWrapper>(new[] { FileWrapper.GetSample(), FileWrapper.GetSample() }),
Folders = new List<FolderWrapper>(new[] { FolderWrapper.GetSample(), FolderWrapper.GetSample() }),
Current = FolderWrapper<int>.GetSample(),
Files = new List<FileWrapper<int>>(new[] { FileWrapper<int>.GetSample(), FileWrapper<int>.GetSample() }),
Folders = new List<FolderWrapper<int>>(new[] { FolderWrapper<int>.GetSample(), FolderWrapper<int>.GetSample() }),
PathParts = new
{
key = "Key",
@ -119,9 +119,9 @@ namespace ASC.Api.Documents
FolderWrapperHelper = folderWrapperHelper;
}
public FolderContentWrapper Get<T>(DataWrapper<T> folderItems, int startIndex)
public FolderContentWrapper<T> Get<T>(DataWrapper<T> folderItems, int startIndex)
{
var result = new FolderContentWrapper
var result = new FolderContentWrapper<T>
{
Files = folderItems.Entries.OfType<File<T>>().Select(FileWrapperHelper.Get).ToList(),
Folders = folderItems.Entries.OfType<Folder<T>>().Select(FolderWrapperHelper.Get).ToList(),

View File

@ -41,12 +41,12 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
[DataContract(Name = "folder", Namespace = "")]
public class FolderWrapper : FileEntryWrapper
public class FolderWrapper<T> : FileEntryWrapper<T>
{
/// <summary>
/// </summary>
[DataMember(IsRequired = true, EmitDefaultValue = true)]
public object ParentId { get; set; }
public T ParentId { get; set; }
/// <summary>
/// </summary>
@ -73,9 +73,9 @@ namespace ASC.Api.Documents
/// <summary>
/// </summary>
/// <returns></returns>
public static FolderWrapper GetSample()
public static FolderWrapper<int> GetSample()
{
return new FolderWrapper
return new FolderWrapper<int>
{
Access = FileShare.ReadWrite,
//Updated = ApiDateTime.GetSample(),
@ -116,9 +116,9 @@ namespace ASC.Api.Documents
GlobalFolderHelper = globalFolderHelper;
}
public FolderWrapper Get<T>(Folder<T> folder)
public FolderWrapper<T> Get<T>(Folder<T> folder)
{
var result = Get<FolderWrapper>(folder);
var result = Get<FolderWrapper<T>, T>(folder);
result.ParentId = folder.ParentFolderID;
if (folder.RootFolderType == FolderType.USER
&& !Equals(folder.RootFolderCreator, AuthContext.CurrentAccount.ID))
@ -128,7 +128,7 @@ namespace ASC.Api.Documents
var folderDao = DaoFactory.GetFolderDao<T>();
var parentFolder = folderDao.GetFolder(folder.ParentFolderID);
if (!FileSecurity.CanRead(parentFolder))
result.ParentId = GlobalFolderHelper.FolderShare;
result.ParentId = GlobalFolderHelper.GetFolderShare<T>();
}
result.FilesCount = folder.TotalFiles;

View File

@ -58,8 +58,6 @@ using ASC.Web.Studio.Utility;
using Microsoft.Extensions.DependencyInjection;
using File = ASC.Files.Core.File;
namespace ASC.Web.Files.Services.DocumentService
{
public enum EditorType

View File

@ -60,7 +60,7 @@ namespace ASC.Web.Files.Services.WCFService
//}
}
public System.IO.MemoryStream ToXml<T>(object o)
public System.IO.MemoryStream ToXml(object o)
{
var result = new System.IO.MemoryStream();
if (o == null)
@ -85,7 +85,7 @@ namespace ASC.Web.Files.Services.WCFService
//remove incorrect ns
foreach (XmlNode entry in xml.SelectNodes("//entry"))
{
var nsattr = entry.Attributes.Cast<XmlAttribute>().FirstOrDefault(a => a.Value == typeof(FileEntry<T>).Name);
var nsattr = entry.Attributes.Cast<XmlAttribute>().FirstOrDefault(a => a.Value == typeof(FileEntry<>).Name);
if (nsattr != null)
{
foreach (XmlAttribute a in entry.Attributes)

View File

@ -111,7 +111,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
MoveOrCopyFolders(scope, Folders, toFolder, _copy);
MoveOrCopyFiles(scope, Files, toFolder, _copy);
_needToMark.Distinct().ToList().ForEach(x => fileMarker.MarkAsNew<T>(x));
_needToMark.Distinct().ToList().ForEach(x => fileMarker.MarkAsNew(x));
}
private void MoveOrCopyFolders(IServiceScope scope, List<T> folderIds, Folder<T> toFolder, bool copy)

View File

@ -600,7 +600,7 @@ namespace ASC.Web.Files.Utils
folder.ProviderId = providerInfo.ID;
folder.ProviderKey = providerInfo.ProviderKey;
folder.RootFolderCreator = providerInfo.Owner;
folder.RootFolderId = providerInfo.RootFolderId;
folder.RootFolderId = (T)Convert.ChangeType(providerInfo.RootFolderId, typeof(T));
folder.RootFolderType = providerInfo.RootFolderType;
folder.Shareable = false;
folder.Title = providerInfo.CustomerTitle;

View File

@ -61,16 +61,353 @@ using SecurityContext = ASC.Core.SecurityContext;
namespace ASC.Web.Files.Utils
{
public class FileConverter
internal class FileConverterQueue<T>
{
private static readonly object locker = new object();
private static readonly IDictionary<File<T>, ConvertFileOperationResult> conversionQueue = new Dictionary<File<T>, ConvertFileOperationResult>(new FileComparer());
private readonly object singleThread = new object();
private readonly IDictionary<File<T>, ConvertFileOperationResult> conversionQueue;
private readonly Timer timer;
private readonly object locker;
private readonly ICache cache;
private static Timer timer;
private static readonly object singleThread = new object();
private const int TIMER_PERIOD = 500;
public IServiceProvider ServiceProvider { get; }
public FileConverterQueue(IServiceProvider ServiceProvider)
{
conversionQueue = new Dictionary<File<T>, ConvertFileOperationResult>(new FileComparer<T>());
timer = new Timer(CheckConvertFilesStatus, null, 0, Timeout.Infinite);
locker = new object();
this.ServiceProvider = ServiceProvider;
cache = AscCache.Memory;
}
public void Add(File<T> file, string password, int tenantId, IAccount account, bool deleteAfter, string url)
{
lock (locker)
{
if (conversionQueue.ContainsKey(file))
{
return;
}
var queueResult = new ConvertFileOperationResult
{
Source = string.Format("{{\"id\":\"{0}\", \"version\":\"{1}\"}}", file.ID, file.Version),
OperationType = FileOperationType.Convert,
Error = string.Empty,
Progress = 0,
Result = string.Empty,
Processed = "",
Id = string.Empty,
TenantId = tenantId,
Account = account,
Delete = deleteAfter,
StartDateTime = DateTime.Now,
Url = url,
Password = password
};
conversionQueue.Add(file, queueResult);
cache.Insert(GetKey(file), queueResult, TimeSpan.FromMinutes(10));
timer.Change(0, Timeout.Infinite);
}
}
public ConvertFileOperationResult GetStatus(KeyValuePair<File<T>, bool> pair, FileSecurity fileSecurity)
{
var file = pair.Key;
var key = GetKey(file);
var operation = cache.Get<ConvertFileOperationResult>(key);
if (operation != null && (pair.Value || fileSecurity.CanRead(file)))
{
lock (locker)
{
if (operation.Progress == 100)
{
conversionQueue.Remove(file);
cache.Remove(key);
}
return operation;
}
}
return null;
}
public bool IsConverting(File<T> file)
{
var result = cache.Get<ConvertFileOperationResult>(GetKey(file));
return result != null && result.Progress != 100 && string.IsNullOrEmpty(result.Error);
}
private void CheckConvertFilesStatus(object _)
{
if (Monitor.TryEnter(singleThread))
{
using var scope = ServiceProvider.CreateScope();
var logger = scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var daoFactory = scope.ServiceProvider.GetService<IDaoFactory>();
var FileSecurity = scope.ServiceProvider.GetService<FileSecurity>();
var PathProvider = scope.ServiceProvider.GetService<PathProvider>();
var SetupInfo = scope.ServiceProvider.GetService<SetupInfo>();
var FileUtility = scope.ServiceProvider.GetService<FileUtility>();
var DocumentServiceHelper = scope.ServiceProvider.GetService<DocumentServiceHelper>();
var DocumentServiceConnector = scope.ServiceProvider.GetService<DocumentServiceConnector>();
var EntryManager = scope.ServiceProvider.GetService<EntryManager>();
var FileConverter = scope.ServiceProvider.GetService<FileConverter>();
try
{
var filesIsConverting = new List<File<T>>();
lock (locker)
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
conversionQueue.Where(x => !string.IsNullOrEmpty(x.Value.Processed)
&& (x.Value.Progress == 100 && DateTime.UtcNow - x.Value.StopDateTime > TimeSpan.FromMinutes(1) ||
DateTime.UtcNow - x.Value.StopDateTime > TimeSpan.FromMinutes(10)))
.ToList()
.ForEach(x =>
{
conversionQueue.Remove(x);
cache.Remove(GetKey(x.Key));
});
logger.DebugFormat("Run CheckConvertFilesStatus: count {0}", conversionQueue.Count);
if (conversionQueue.Count == 0)
{
return;
}
filesIsConverting = conversionQueue
.Where(x => string.IsNullOrEmpty(x.Value.Processed))
.Select(x => x.Key)
.ToList();
}
var fileSecurity = FileSecurity;
foreach (var file in filesIsConverting)
{
var fileUri = file.ID.ToString();
string convertedFileUrl;
int operationResultProgress;
try
{
int tenantId;
IAccount account;
string password;
lock (locker)
{
if (!conversionQueue.Keys.Contains(file)) continue;
var operationResult = conversionQueue[file];
if (!string.IsNullOrEmpty(operationResult.Processed)) continue;
operationResult.Processed = "1";
tenantId = operationResult.TenantId;
account = operationResult.Account;
password = operationResult.Password;
//if (HttpContext.Current == null && !WorkContext.IsMono)
//{
// HttpContext.Current = new HttpContext(
// new HttpRequest("hack", operationResult.Url, string.Empty),
// new HttpResponse(new StringWriter()));
//}
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
tenantManager.SetCurrentTenant(tenantId);
securityContext.AuthenticateMe(account);
var user = userManager.GetUsers(account.ID);
var culture = string.IsNullOrEmpty(user.CultureName) ? tenantManager.GetCurrentTenant().GetCulture() : CultureInfo.GetCultureInfo(user.CultureName);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
if (!fileSecurity.CanRead(file) && file.RootFolderType != FolderType.BUNCH)
{
//No rights in CRM after upload before attach
throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_ReadFile);
}
if (file.ContentLength > SetupInfo.AvailableFileSize)
{
throw new Exception(string.Format(FilesCommonResource.ErrorMassage_FileSizeConvert, FileSizeComment.FilesSizeToString(SetupInfo.AvailableFileSize)));
}
fileUri = PathProvider.GetFileStreamUrl(file);
var toExtension = FileUtility.GetInternalExtension(file.Title);
var fileExtension = file.ConvertedExtension;
var docKey = DocumentServiceHelper.GetDocKey(file);
fileUri = DocumentServiceConnector.ReplaceCommunityAdress(fileUri);
operationResultProgress = DocumentServiceConnector.GetConvertedUri(fileUri, fileExtension, toExtension, docKey, password, true, out convertedFileUrl);
}
catch (Exception exception)
{
var password = exception.InnerException != null
&& (exception.InnerException is DocumentService.DocumentServiceException documentServiceException)
&& documentServiceException.Code == DocumentService.DocumentServiceException.ErrorCode.ConvertPassword;
logger.Error(string.Format("Error convert {0} with url {1}", file.ID, fileUri), exception);
lock (locker)
{
if (conversionQueue.Keys.Contains(file))
{
var operationResult = conversionQueue[file];
if (operationResult.Delete)
{
conversionQueue.Remove(file);
cache.Remove(GetKey(file));
}
else
{
operationResult.Progress = 100;
operationResult.StopDateTime = DateTime.UtcNow;
operationResult.Error = exception.Message;
if (password) operationResult.Result = "password";
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
}
}
continue;
}
operationResultProgress = Math.Min(operationResultProgress, 100);
if (operationResultProgress < 100)
{
lock (locker)
{
if (conversionQueue.Keys.Contains(file))
{
var operationResult = conversionQueue[file];
if (DateTime.Now - operationResult.StartDateTime > TimeSpan.FromMinutes(10))
{
operationResult.StopDateTime = DateTime.UtcNow;
operationResult.Error = FilesCommonResource.ErrorMassage_ConvertTimeout;
logger.ErrorFormat("CheckConvertFilesStatus timeout: {0} ({1})", file.ID, file.ContentLengthString);
}
else
{
operationResult.Processed = "";
}
operationResult.Progress = operationResultProgress;
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
}
logger.Debug("CheckConvertFilesStatus iteration continue");
continue;
}
File<T> newFile = null;
var operationResultError = string.Empty;
try
{
newFile = FileConverter.SaveConvertedFile(file, convertedFileUrl);
}
catch (Exception e)
{
operationResultError = e.Message;
logger.ErrorFormat("{0} ConvertUrl: {1} fromUrl: {2}: {3}", operationResultError, convertedFileUrl, fileUri, e);
continue;
}
finally
{
lock (locker)
{
if (conversionQueue.Keys.Contains(file))
{
var operationResult = conversionQueue[file];
if (operationResult.Delete)
{
conversionQueue.Remove(file);
cache.Remove(GetKey(file));
}
else
{
if (newFile != null)
{
var folderDao = daoFactory.GetFolderDao<T>();
var folder = folderDao.GetFolder(newFile.FolderID);
var folderTitle = fileSecurity.CanRead(folder) ? folder.Title : null;
operationResult.Result = FileJsonSerializer(EntryManager, newFile, folderTitle);
}
operationResult.Progress = 100;
operationResult.StopDateTime = DateTime.UtcNow;
operationResult.Processed = "1";
if (!string.IsNullOrEmpty(operationResultError))
{
operationResult.Error = operationResultError;
}
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
}
}
}
logger.Debug("CheckConvertFilesStatus iteration end");
}
lock (locker)
{
timer.Change(TIMER_PERIOD, TIMER_PERIOD);
}
}
catch (Exception exception)
{
logger.Error(exception.Message, exception);
lock (locker)
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
finally
{
Monitor.Exit(singleThread);
}
}
}
private string GetKey(File<T> f)
{
return string.Format("fileConvertation-{0}", f.ID);
}
private string FileJsonSerializer(EntryManager EntryManager, File<T> file, string folderTitle)
{
if (file == null) return string.Empty;
EntryManager.SetFileStatus(file);
return
string.Format("{{ \"id\": \"{0}\"," +
" \"title\": \"{1}\"," +
" \"version\": \"{2}\"," +
" \"folderId\": \"{3}\"," +
" \"folderTitle\": \"{4}\"," +
" \"fileXml\": \"{5}\" }}",
file.ID,
file.Title,
file.Version,
file.FolderID,
folderTitle ?? "",
File<T>.Serialize(file).Replace('"', '\''));
}
}
public class FileConverter
{
public FileUtility FileUtility { get; }
public FilesLinkUtility FilesLinkUtility { get; }
public IDaoFactory DaoFactory { get; }
@ -89,7 +426,6 @@ namespace ASC.Web.Files.Utils
public DocumentServiceConnector DocumentServiceConnector { get; }
public IServiceProvider ServiceProvider { get; }
public IHttpContextAccessor HttpContextAccesor { get; }
public ILog Logger { get; }
public FileConverter(
FileUtility fileUtility,
@ -128,8 +464,6 @@ namespace ASC.Web.Files.Utils
DocumentServiceHelper = documentServiceHelper;
DocumentServiceConnector = documentServiceConnector;
ServiceProvider = serviceProvider;
Logger = options.CurrentValue;
cache = AscCache.Memory;
}
public FileConverter(
FileUtility fileUtility,
@ -269,42 +603,7 @@ namespace ASC.Web.Files.Utils
}
FileMarker.RemoveMarkAsNew(file);
lock (locker)
{
if (conversionQueue.ContainsKey(file))
{
return;
}
var queueResult = new ConvertFileOperationResult
{
Source = string.Format("{{\"id\":\"{0}\", \"version\":\"{1}\"}}", file.ID, file.Version),
OperationType = FileOperationType.Convert,
Error = string.Empty,
Progress = 0,
Result = string.Empty,
Processed = "",
Id = string.Empty,
TenantId = TenantManager.GetCurrentTenant().TenantId,
Account = AuthContext.CurrentAccount,
Delete = deleteAfter,
StartDateTime = DateTime.Now,
Url = HttpContextAccesor?.HttpContext != null ? HttpContextAccesor.HttpContext.Request.GetUrlRewriter().ToString() : null,
Password = password
};
conversionQueue.Add(file, queueResult);
cache.Insert(GetKey(file), queueResult, TimeSpan.FromMinutes(10));
if (timer == null)
{
timer = new Timer(CheckConvertFilesStatus, null, 0, Timeout.Infinite);
}
else
{
timer.Change(0, Timeout.Infinite);
}
}
GetFileConverter<T>().Add(file, password, TenantManager.GetCurrentTenant().TenantId, AuthContext.CurrentAccount, deleteAfter, HttpContextAccesor?.HttpContext != null ? HttpContextAccesor.HttpContext.Request.GetUrlRewriter().ToString() : null);
}
public bool IsConverting<T>(File<T> file)
@ -313,289 +612,26 @@ namespace ASC.Web.Files.Utils
{
return false;
}
var result = cache.Get<ConvertFileOperationResult>(GetKey(file));
return result != null && result.Progress != 100 && string.IsNullOrEmpty(result.Error);
return GetFileConverter<T>().IsConverting(file);
}
public IEnumerable<FileOperationResult> GetStatus<T>(IEnumerable<KeyValuePair<File<T>, bool>> filesPair)
{
var fileSecurity = FileSecurity;
var result = new List<FileOperationResult>();
foreach (var pair in filesPair)
{
var file = pair.Key;
var key = GetKey(file);
var operation = cache.Get<ConvertFileOperationResult>(key);
if (operation != null && (pair.Value || fileSecurity.CanRead(file)))
var r = GetFileConverter<T>().GetStatus(pair, FileSecurity);
if (r != null)
{
result.Add(operation);
lock (locker)
{
if (operation.Progress == 100)
{
conversionQueue.Remove(file);
cache.Remove(key);
}
}
result.Add(r);
}
}
return result;
}
private string FileJsonSerializer<T>(File<T> file, string folderTitle)
{
if (file == null) return string.Empty;
EntryManager.SetFileStatus(file);
return
string.Format("{{ \"id\": \"{0}\"," +
" \"title\": \"{1}\"," +
" \"version\": \"{2}\"," +
" \"folderId\": \"{3}\"," +
" \"folderTitle\": \"{4}\"," +
" \"fileXml\": \"{5}\" }}",
file.ID,
file.Title,
file.Version,
file.FolderID,
folderTitle ?? "",
File<T>.Serialize(file).Replace('"', '\''));
}
private void CheckConvertFilesStatus<T>(object _)
{
if (Monitor.TryEnter(singleThread))
{
using var scope = ServiceProvider.CreateScope();
var logger = scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var daoFactory = scope.ServiceProvider.GetService<IDaoFactory>();
try
{
var filesIsConverting = new List<File<T>>();
lock (locker)
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
conversionQueue.Where(x => !string.IsNullOrEmpty(x.Value.Processed)
&& (x.Value.Progress == 100 && DateTime.UtcNow - x.Value.StopDateTime > TimeSpan.FromMinutes(1) ||
DateTime.UtcNow - x.Value.StopDateTime > TimeSpan.FromMinutes(10)))
.ToList()
.ForEach(x =>
{
conversionQueue.Remove(x);
cache.Remove(GetKey(x.Key));
});
logger.DebugFormat("Run CheckConvertFilesStatus: count {0}", conversionQueue.Count);
if (conversionQueue.Count == 0)
{
return;
}
filesIsConverting = conversionQueue
.Where(x => string.IsNullOrEmpty(x.Value.Processed))
.Select(x => x.Key)
.ToList();
}
var fileSecurity = FileSecurity;
foreach (var file in filesIsConverting)
{
var fileUri = file.ID.ToString();
string convertedFileUrl;
int operationResultProgress;
try
{
int tenantId;
IAccount account;
string password;
lock (locker)
{
if (!conversionQueue.Keys.Contains(file)) continue;
var operationResult = conversionQueue[file];
if (!string.IsNullOrEmpty(operationResult.Processed)) continue;
operationResult.Processed = "1";
tenantId = operationResult.TenantId;
account = operationResult.Account;
password = operationResult.Password;
//if (HttpContext.Current == null && !WorkContext.IsMono)
//{
// HttpContext.Current = new HttpContext(
// new HttpRequest("hack", operationResult.Url, string.Empty),
// new HttpResponse(new StringWriter()));
//}
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
tenantManager.SetCurrentTenant(tenantId);
securityContext.AuthenticateMe(account);
var user = userManager.GetUsers(account.ID);
var culture = string.IsNullOrEmpty(user.CultureName) ? TenantManager.GetCurrentTenant().GetCulture() : CultureInfo.GetCultureInfo(user.CultureName);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
if (!fileSecurity.CanRead(file) && file.RootFolderType != FolderType.BUNCH)
{
//No rights in CRM after upload before attach
throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_ReadFile);
}
if (file.ContentLength > SetupInfo.AvailableFileSize)
{
throw new Exception(string.Format(FilesCommonResource.ErrorMassage_FileSizeConvert, FileSizeComment.FilesSizeToString(SetupInfo.AvailableFileSize)));
}
fileUri = PathProvider.GetFileStreamUrl(file);
var toExtension = FileUtility.GetInternalExtension(file.Title);
var fileExtension = file.ConvertedExtension;
var docKey = DocumentServiceHelper.GetDocKey(file);
fileUri = DocumentServiceConnector.ReplaceCommunityAdress(fileUri);
operationResultProgress = DocumentServiceConnector.GetConvertedUri(fileUri, fileExtension, toExtension, docKey, password, true, out convertedFileUrl);
}
catch (Exception exception)
{
var password = exception.InnerException != null
&& (exception.InnerException is DocumentService.DocumentServiceException documentServiceException)
&& documentServiceException.Code == DocumentService.DocumentServiceException.ErrorCode.ConvertPassword;
logger.Error(string.Format("Error convert {0} with url {1}", file.ID, fileUri), exception);
lock (locker)
{
if (conversionQueue.Keys.Contains(file))
{
var operationResult = conversionQueue[file];
if (operationResult.Delete)
{
conversionQueue.Remove(file);
cache.Remove(GetKey(file));
}
else
{
operationResult.Progress = 100;
operationResult.StopDateTime = DateTime.UtcNow;
operationResult.Error = exception.Message;
if (password) operationResult.Result = "password";
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
}
}
continue;
}
operationResultProgress = Math.Min(operationResultProgress, 100);
if (operationResultProgress < 100)
{
lock (locker)
{
if (conversionQueue.Keys.Contains(file))
{
var operationResult = conversionQueue[file];
if (DateTime.Now - operationResult.StartDateTime > TimeSpan.FromMinutes(10))
{
operationResult.StopDateTime = DateTime.UtcNow;
operationResult.Error = FilesCommonResource.ErrorMassage_ConvertTimeout;
logger.ErrorFormat("CheckConvertFilesStatus timeout: {0} ({1})", file.ID, file.ContentLengthString);
}
else
{
operationResult.Processed = "";
}
operationResult.Progress = operationResultProgress;
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
}
logger.Debug("CheckConvertFilesStatus iteration continue");
continue;
}
File<T> newFile = null;
var operationResultError = string.Empty;
try
{
newFile = SaveConvertedFile(file, convertedFileUrl);
}
catch (Exception e)
{
operationResultError = e.Message;
logger.ErrorFormat("{0} ConvertUrl: {1} fromUrl: {2}: {3}", operationResultError, convertedFileUrl, fileUri, e);
continue;
}
finally
{
lock (locker)
{
if (conversionQueue.Keys.Contains(file))
{
var operationResult = conversionQueue[file];
if (operationResult.Delete)
{
conversionQueue.Remove(file);
cache.Remove(GetKey(file));
}
else
{
if (newFile != null)
{
var folderDao = daoFactory.GetFolderDao<T>();
var folder = folderDao.GetFolder(newFile.FolderID);
var folderTitle = fileSecurity.CanRead(folder) ? folder.Title : null;
operationResult.Result = FileJsonSerializer(newFile, folderTitle);
}
operationResult.Progress = 100;
operationResult.StopDateTime = DateTime.UtcNow;
operationResult.Processed = "1";
if (!string.IsNullOrEmpty(operationResultError))
{
operationResult.Error = operationResultError;
}
cache.Insert(GetKey(file), operationResult, TimeSpan.FromMinutes(10));
}
}
}
}
logger.Debug("CheckConvertFilesStatus iteration end");
}
lock (locker)
{
timer.Change(TIMER_PERIOD, TIMER_PERIOD);
}
}
catch (Exception exception)
{
logger.Error(exception.Message, exception);
lock (locker)
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
finally
{
Monitor.Exit(singleThread);
}
}
}
private File<T> SaveConvertedFile<T>(File<T> file, string convertedFileUrl)
public File<T> SaveConvertedFile<T>(File<T> file, string convertedFileUrl)
{
var fileSecurity = FileSecurity;
var fileDao = DaoFactory.GetFileDao<T>();
@ -681,7 +717,7 @@ namespace ASC.Web.Files.Utils
}
FilesMessageService.Send(newFile, MessageInitiator.DocsService, MessageAction.FileConverted, newFile.Title);
FileMarker.MarkAsNew<T>(newFile);
FileMarker.MarkAsNew(newFile);
var tagDao = DaoFactory.GetTagDao<T>();
var tags = tagDao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList();
@ -694,36 +730,32 @@ namespace ASC.Web.Files.Utils
return newFile;
}
private static string GetKey<T>(File<T> f)
private FileConverterQueue<T> GetFileConverter<T>() => ServiceProvider.GetService<FileConverterQueue<T>>();
}
internal class FileComparer<T> : IEqualityComparer<File<T>>
{
public bool Equals(File<T> x, File<T> y)
{
return string.Format("fileConvertation-{0}", f.ID);
return x != null && y != null && Equals(x.ID, y.ID) && x.Version == y.Version;
}
private class FileComparer<T> : IEqualityComparer<File<T>>
public int GetHashCode(File<T> obj)
{
public bool Equals(File<T> x, File<T> y)
{
return x != null && y != null && Equals(x.ID, y.ID) && x.Version == y.Version;
}
public int GetHashCode(File<T> obj)
{
return obj.ID.GetHashCode() + obj.Version.GetHashCode();
}
return obj.ID.GetHashCode() + obj.Version.GetHashCode();
}
}
[DataContract(Name = "operation_result", Namespace = "")]
private class ConvertFileOperationResult : FileOperationResult
{
public DateTime StartDateTime { get; set; }
public DateTime StopDateTime { get; set; }
public int TenantId { get; set; }
public IAccount Account { get; set; }
public bool Delete { get; set; }
public string Url { get; set; }
public string Password { get; set; }
}
[DataContract(Name = "operation_result", Namespace = "")]
internal class ConvertFileOperationResult : FileOperationResult
{
public DateTime StartDateTime { get; set; }
public DateTime StopDateTime { get; set; }
public int TenantId { get; set; }
public IAccount Account { get; set; }
public bool Delete { get; set; }
public string Url { get; set; }
public string Password { get; set; }
}
public static class FileConverterExtension
@ -731,6 +763,8 @@ namespace ASC.Web.Files.Utils
public static DIHelper AddFileConverterService(this DIHelper services)
{
services.TryAddScoped<FileConverter>();
services.TryAddSingleton<FileConverterQueue<string>>();
services.TryAddSingleton<FileConverterQueue<int>>();
return services
.AddFilesLinkUtilityService()
.AddFileUtilityService()

View File

@ -46,18 +46,41 @@ using Microsoft.Extensions.Options;
namespace ASC.Web.Files.Utils
{
public class FileMarkerHelper
public class FileMarkerHelper<T>
{
private IServiceProvider ServiceProvider { get; }
public ILog Log { get; }
public FileMarkerHelper(IServiceProvider serviceProvider, IOptionsMonitor<ILog> optionsMonitor)
public object Locker { get; set; }
public WorkerQueue<AsyncTaskData<T>> Tasks { get; set; }
public FileMarkerHelper(
IServiceProvider serviceProvider,
IOptionsMonitor<ILog> optionsMonitor,
WorkerQueueOptionsManager<AsyncTaskData<T>> workerQueueOptionsManager)
{
ServiceProvider = serviceProvider;
Log = optionsMonitor.CurrentValue;
Locker = new object();
Tasks = workerQueueOptionsManager.Value;
}
internal void ExecMarkFileAsNew<T>(AsyncTaskData<T> obj)
internal void Add(AsyncTaskData<T> taskData)
{
lock (Locker)
{
Tasks.Add(taskData);
if (!Tasks.IsStarted)
{
Tasks.Start(ExecMarkFileAsNew);
}
}
}
private void ExecMarkFileAsNew(AsyncTaskData<T> obj)
{
try
{
@ -70,13 +93,10 @@ namespace ASC.Web.Files.Utils
Log.Error(e);
}
}
}
public class FileMarker
{
private static readonly object locker = new object();
private readonly WorkerQueue<AsyncTaskData<T>> tasks;
private readonly ICache cache;
private const string CacheKeyFormat = "MarkedAsNew/{0}/folder_{1}";
@ -89,7 +109,6 @@ namespace ASC.Web.Files.Utils
public CoreBaseSettings CoreBaseSettings { get; }
public AuthContext AuthContext { get; }
public IServiceProvider ServiceProvider { get; }
public FileMarkerHelper FileMarkerHelper { get; }
public FileMarker(
TenantManager tenantManager,
@ -99,9 +118,7 @@ namespace ASC.Web.Files.Utils
FileSecurity fileSecurity,
CoreBaseSettings coreBaseSettings,
AuthContext authContext,
IServiceProvider serviceProvider,
WorkerQueueOptionsManager<AsyncTaskData<T>> workerQueueOptionsManager,
FileMarkerHelper fileMarkerHelper)
IServiceProvider serviceProvider)
{
TenantManager = tenantManager;
UserManager = userManager;
@ -111,9 +128,7 @@ namespace ASC.Web.Files.Utils
CoreBaseSettings = coreBaseSettings;
AuthContext = authContext;
ServiceProvider = serviceProvider;
FileMarkerHelper = fileMarkerHelper;
cache = AscCache.Memory;
tasks = workerQueueOptionsManager.Value;
}
internal void ExecMarkFileAsNew<T>(AsyncTaskData<T> obj)
@ -224,7 +239,7 @@ namespace ASC.Web.Files.Utils
if (obj.FileEntry.ProviderEntry)
{
var commonFolder = folderDao.GetFolder(GlobalFolder.GetFolderCommon(this, DaoFactory));
var commonFolder = folderDao.GetFolder(GlobalFolder.GetFolderCommon<T>(this, DaoFactory));
userIDs.ForEach(userID =>
{
if (userEntriesData.ContainsKey(userID))
@ -304,13 +319,7 @@ namespace ASC.Web.Files.Utils
taskData.UserIDs = projectTeam;
}
lock (locker)
{
tasks.Add(taskData);
if (!tasks.IsStarted)
tasks.Start(FileMarkerHelper.ExecMarkFileAsNew);
}
ServiceProvider.GetService<FileMarkerHelper<T>>().Add(taskData);
}
public void RemoveMarkAsNew<T>(FileEntry<T> fileEntry, Guid userID = default)
@ -349,7 +358,7 @@ namespace ASC.Web.Files.Utils
{
var folderTags = listTags.Where(tag => tag.EntryType == FileEntryType.Folder);
var providerFolderTags = folderTags.Select(tag => new KeyValuePair<Tag, Folder<T>>(tag, folderDao.GetFolder(tag.EntryId)))
var providerFolderTags = folderTags.Select(tag => new KeyValuePair<Tag, Folder<T>>(tag, folderDao.GetFolder((T)tag.EntryId)))
.Where(pair => pair.Value != null && pair.Value.ProviderEntry).ToList();
foreach (var providerFolderTag in providerFolderTags)
@ -378,9 +387,9 @@ namespace ASC.Web.Files.Utils
else if (rootFolder.RootFolderType == FolderType.COMMON)
{
if (rootFolder.ProviderEntry)
cacheFolderId = rootFolderId = GlobalFolder.GetFolderCommon(this, DaoFactory);
cacheFolderId = rootFolderId = GlobalFolder.GetFolderCommon<T>(this, DaoFactory);
else
cacheFolderId = GlobalFolder.GetFolderCommon(this, DaoFactory);
cacheFolderId = GlobalFolder.GetFolderCommon<T>(this, DaoFactory);
}
else if (rootFolder.RootFolderType == FolderType.USER)
{
@ -450,8 +459,8 @@ namespace ASC.Web.Files.Utils
{
var rootIds = new List<T>
{
GlobalFolder.GetFolderMy(this, DaoFactory),
GlobalFolder.GetFolderCommon(this, DaoFactory),
GlobalFolder.GetFolderMy<T>(this, DaoFactory),
GlobalFolder.GetFolderCommon<T>(this, DaoFactory),
GlobalFolder.GetFolderShare<T>(DaoFactory),
GlobalFolder.GetFolderProjects<T>(DaoFactory)
};
@ -727,7 +736,6 @@ namespace ASC.Web.Files.Utils
{
public static DIHelper AddFileMarkerService(this DIHelper services)
{
return services
.AddFileMarkerService<string>()
.AddFileMarkerService<int>()
@ -739,7 +747,7 @@ namespace ASC.Web.Files.Utils
_ = services
.TryAddTransient<AsyncTaskData<T>>()
.TryAddScoped<FileMarker>()
.TryAddSingleton<FileMarkerHelper>()
.TryAddSingleton<FileMarkerHelper<T>>()
.TryAddSingleton<WorkerQueueOptionsManager<AsyncTaskData<T>>>()
.TryAddSingleton<WorkerQueue<AsyncTaskData<T>>>()
.AddSingleton<IConfigureOptions<WorkerQueue<AsyncTaskData<T>>>, ConfigureWorkerQueue<AsyncTaskData<T>>>();