commit
dedd754875
@ -52,10 +52,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppLimit.CloudComputing.Sha
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files.Service", "products\ASC.Files\Service\ASC.Files.Service.csproj", "{5D41FFFF-816C-40B2-95CD-E2DDDCB83784}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.ApiSystem", "common\services\ASC.ApiSystem\ASC.ApiSystem.csproj", "{C2BB03A0-C35B-433F-96D4-3A06CBC06AD7}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ApiSystem", "common\services\ASC.ApiSystem\ASC.ApiSystem.csproj", "{C2BB03A0-C35B-433F-96D4-3A06CBC06AD7}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.UrlShortener.Svc", "common\services\ASC.UrlShortener.Svc\ASC.UrlShortener.Svc.csproj", "{04A56018-C41E-4634-A185-A13E9250C75A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.Feed.Aggregator", "common\services\ASC.Feed.Aggregator\ASC.Feed.Aggregator.csproj", "{07CCC11F-76CB-448E-B15A-72E09FBB348B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -162,6 +164,10 @@ Global
|
||||
{04A56018-C41E-4634-A185-A13E9250C75A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04A56018-C41E-4634-A185-A13E9250C75A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04A56018-C41E-4634-A185-A13E9250C75A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{07CCC11F-76CB-448E-B15A-72E09FBB348B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{07CCC11F-76CB-448E-B15A-72E09FBB348B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07CCC11F-76CB-448E-B15A-72E09FBB348B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07CCC11F-76CB-448E-B15A-72E09FBB348B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -231,6 +231,13 @@ namespace ASC.Core.Common
|
||||
|
||||
return baseUri.ToString().TrimEnd('/');
|
||||
}
|
||||
|
||||
public void Initialize(string serverUri)
|
||||
{
|
||||
var uri = new Uri(serverUri.Replace('*', 'x').Replace('+', 'x'));
|
||||
_serverRoot = new UriBuilder(uri.Scheme, LOCALHOST, uri.Port);
|
||||
_vpath = "/" + uri.AbsolutePath.Trim('/');
|
||||
}
|
||||
}
|
||||
|
||||
public static class BaseCommonLinkUtilityExtension
|
||||
|
@ -74,6 +74,16 @@ namespace ASC.Core
|
||||
|
||||
}
|
||||
|
||||
public UserManager(
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IUserService service,
|
||||
TenantManager tenantManager,
|
||||
PermissionContext permissionContext,
|
||||
UserManagerConstants userManagerConstants) : this(service, tenantManager, permissionContext, userManagerConstants)
|
||||
{
|
||||
Accessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public UserManager(
|
||||
IUserService service,
|
||||
TenantManager tenantManager,
|
||||
|
@ -8,7 +8,10 @@ namespace ASC.Core.Common.EF.Model
|
||||
[Table("feed_users")]
|
||||
public class FeedUsers : BaseEntity
|
||||
{
|
||||
[Column("feed_id")]
|
||||
public string FeedId { get; set; }
|
||||
|
||||
[Column("user_id")]
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
public override object[] GetKeys() => new object[] { FeedId, UserId };
|
||||
|
@ -49,7 +49,8 @@ namespace ASC.Feed.Data
|
||||
public TenantUtil TenantUtil { get; }
|
||||
public FeedDbContext FeedDbContext { get; }
|
||||
|
||||
public FeedAggregateDataProvider(DbContextManager<FeedDbContext> dbContextManager)
|
||||
public FeedAggregateDataProvider(AuthContext authContext, TenantManager tenantManager, TenantUtil tenantUtil, DbContextManager<FeedDbContext> dbContextManager)
|
||||
: this(authContext, tenantManager, tenantUtil)
|
||||
{
|
||||
FeedDbContext = dbContextManager.Get(Constants.FeedDbId);
|
||||
}
|
||||
@ -124,7 +125,10 @@ namespace ASC.Feed.Data
|
||||
if (f.ClearRightsBeforeInsert)
|
||||
{
|
||||
var fu = FeedDbContext.FeedUsers.Where(r => r.FeedId == f.Id).FirstOrDefault();
|
||||
FeedDbContext.FeedUsers.Remove(fu);
|
||||
if (fu != null)
|
||||
{
|
||||
FeedDbContext.FeedUsers.Remove(fu);
|
||||
}
|
||||
}
|
||||
|
||||
FeedDbContext.AddOrUpdate(r => r.FeedAggregates, feedAggregate);
|
||||
@ -382,6 +386,8 @@ namespace ASC.Feed.Data
|
||||
{
|
||||
public static DIHelper AddFeedAggregateDataProvider(this DIHelper services)
|
||||
{
|
||||
services.TryAddScoped<FeedAggregateDataProvider>();
|
||||
|
||||
return services
|
||||
.AddAuthContextService()
|
||||
.AddTenantManagerService()
|
||||
|
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Feed\ASC.Feed.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Modules\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace ASC.Feed.Configuration
|
||||
{
|
||||
public class FeedSettings
|
||||
{
|
||||
public string ServerRoot { get; set; }
|
||||
|
||||
public TimeSpan AggregatePeriod { get; set; }
|
||||
|
||||
public TimeSpan AggregateInterval { get; set; }
|
||||
|
||||
public TimeSpan RemovePeriod { get; set; }
|
||||
|
||||
public static FeedSettings GetInstance(IConfiguration configuration)
|
||||
{
|
||||
var result = configuration.GetSetting<FeedSettings>("feed");
|
||||
|
||||
if (string.IsNullOrEmpty(result.ServerRoot))
|
||||
{
|
||||
result.ServerRoot = "http://*/";
|
||||
}
|
||||
|
||||
if (result.AggregatePeriod == TimeSpan.Zero)
|
||||
{
|
||||
result.AggregatePeriod = TimeSpan.FromMinutes(5);
|
||||
}
|
||||
|
||||
if (result.AggregateInterval == TimeSpan.Zero)
|
||||
{
|
||||
result.AggregateInterval = TimeSpan.FromDays(14);
|
||||
}
|
||||
|
||||
if (result.RemovePeriod == TimeSpan.Zero)
|
||||
{
|
||||
result.RemovePeriod = TimeSpan.FromDays(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
131
common/services/ASC.Feed.Aggregator/Modules/FeedModule.cs
Normal file
131
common/services/ASC.Feed.Aggregator/Modules/FeedModule.cs
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* 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 ASC.Core;
|
||||
using ASC.Feed.Data;
|
||||
using ASC.Web.Core;
|
||||
|
||||
namespace ASC.Feed.Aggregator.Modules
|
||||
{
|
||||
public abstract class FeedModule : IFeedModule
|
||||
{
|
||||
public abstract string Name { get; }
|
||||
public abstract string Product { get; }
|
||||
public abstract Guid ProductID { get; }
|
||||
|
||||
protected abstract string DbId { get; }
|
||||
|
||||
protected int Tenant
|
||||
{
|
||||
get { return TenantManager.GetCurrentTenant().TenantId; }
|
||||
}
|
||||
|
||||
public TenantManager TenantManager { get; }
|
||||
public WebItemSecurity WebItemSecurity { get; }
|
||||
|
||||
public FeedModule(TenantManager tenantManager, WebItemSecurity webItemSecurity)
|
||||
{
|
||||
TenantManager = tenantManager;
|
||||
WebItemSecurity = webItemSecurity;
|
||||
}
|
||||
|
||||
protected string GetGroupId(string item, Guid author, string rootId = null, int action = -1)
|
||||
{
|
||||
const int interval = 2;
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var hours = now.Hour;
|
||||
var groupIdHours = hours - (hours % interval);
|
||||
|
||||
if (rootId == null)
|
||||
{
|
||||
// groupId = {item}_{author}_{date}
|
||||
return string.Format("{0}_{1}_{2}",
|
||||
item,
|
||||
author,
|
||||
now.ToString("yyyy.MM.dd.") + groupIdHours);
|
||||
}
|
||||
if (action == -1)
|
||||
{
|
||||
// groupId = {item}_{author}_{date}_{rootId}_{action}
|
||||
return string.Format("{0}_{1}_{2}_{3}",
|
||||
item,
|
||||
author,
|
||||
now.ToString("yyyy.MM.dd.") + groupIdHours,
|
||||
rootId);
|
||||
}
|
||||
|
||||
// groupId = {item}_{author}_{date}_{rootId}_{action}
|
||||
return string.Format("{0}_{1}_{2}_{3}_{4}",
|
||||
item,
|
||||
author,
|
||||
now.ToString("yyyy.MM.dd.") + groupIdHours,
|
||||
rootId,
|
||||
action);
|
||||
}
|
||||
|
||||
|
||||
public abstract IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime);
|
||||
|
||||
public abstract IEnumerable<Tuple<Feed, object>> GetFeeds(FeedFilter filter);
|
||||
|
||||
public virtual bool VisibleFor(Feed feed, object data, Guid userId)
|
||||
{
|
||||
return WebItemSecurity.IsAvailableForUser(ProductID, userId);
|
||||
}
|
||||
|
||||
public virtual void VisibleFor(List<Tuple<FeedRow, object>> feed, Guid userId)
|
||||
{
|
||||
if (!WebItemSecurity.IsAvailableForUser(ProductID, userId)) return;
|
||||
|
||||
foreach (var tuple in feed)
|
||||
{
|
||||
if (VisibleFor(tuple.Item1.Feed, tuple.Item2, userId))
|
||||
{
|
||||
tuple.Item1.Users.Add(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static Guid ToGuid(object guid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var str = guid as string;
|
||||
return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
47
common/services/ASC.Feed.Aggregator/Modules/IFeedModule.cs
Normal file
47
common/services/ASC.Feed.Aggregator/Modules/IFeedModule.cs
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* 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 ASC.Feed.Data;
|
||||
|
||||
namespace ASC.Feed.Aggregator.Modules
|
||||
{
|
||||
public interface IFeedModule
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
string Product { get; }
|
||||
|
||||
IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime);
|
||||
|
||||
IEnumerable<Tuple<Feed, object>> GetFeeds(FeedFilter filter);
|
||||
|
||||
bool VisibleFor(Feed feed, object data, Guid userId);
|
||||
|
||||
void VisibleFor(List<Tuple<FeedRow, object>> feed, Guid userId);
|
||||
}
|
||||
}
|
@ -0,0 +1,306 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* 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.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Common;
|
||||
using ASC.Feed.Aggregator.Modules;
|
||||
using ASC.Feed.Configuration;
|
||||
using ASC.Feed.Data;
|
||||
|
||||
using Autofac;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.Feed.Aggregator
|
||||
{
|
||||
public class FeedAggregatorService : IHostedService
|
||||
{
|
||||
private ILog Log { get; set; }
|
||||
//private static readonly SignalrServiceClient signalrServiceClient = new SignalrServiceClient("counters");//TODO
|
||||
|
||||
private Timer aggregateTimer;
|
||||
private Timer removeTimer;
|
||||
|
||||
private volatile bool isStopped;
|
||||
private readonly object aggregateLock = new object();
|
||||
private readonly object removeLock = new object();
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
public IContainer Container { get; }
|
||||
|
||||
public FeedAggregatorService(
|
||||
IConfiguration configuration,
|
||||
IServiceProvider serviceProvider,
|
||||
IContainer container,
|
||||
IOptionsMonitor<ILog> optionsMonitor)
|
||||
{
|
||||
Configuration = configuration;
|
||||
ServiceProvider = serviceProvider;
|
||||
Container = container;
|
||||
Log = optionsMonitor.Get("ASC.Feed.Agregator");
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var cfg = FeedSettings.GetInstance(Configuration);
|
||||
isStopped = false;
|
||||
|
||||
aggregateTimer = new Timer(AggregateFeeds, cfg.AggregateInterval, TimeSpan.Zero, cfg.AggregatePeriod);
|
||||
removeTimer = new Timer(RemoveFeeds, cfg.AggregateInterval, cfg.RemovePeriod, cfg.RemovePeriod);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
isStopped = true;
|
||||
|
||||
if (aggregateTimer != null)
|
||||
{
|
||||
aggregateTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
aggregateTimer.Dispose();
|
||||
aggregateTimer = null;
|
||||
}
|
||||
|
||||
if (removeTimer != null)
|
||||
{
|
||||
removeTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
removeTimer.Dispose();
|
||||
removeTimer = null;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void AggregateFeeds(object interval)
|
||||
{
|
||||
if (!Monitor.TryEnter(aggregateLock)) return;
|
||||
|
||||
try
|
||||
{
|
||||
var cfg = FeedSettings.GetInstance(Configuration);
|
||||
using var scope = ServiceProvider.CreateScope();
|
||||
var commonLinkUtility = scope.ServiceProvider.GetService<BaseCommonLinkUtility>();
|
||||
commonLinkUtility.Initialize(cfg.ServerRoot);
|
||||
|
||||
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
|
||||
var feedAggregateDataProvider = scope.ServiceProvider.GetService<FeedAggregateDataProvider>();
|
||||
|
||||
var start = DateTime.UtcNow;
|
||||
Log.DebugFormat("Start of collecting feeds...");
|
||||
|
||||
var unreadUsers = new Dictionary<int, Dictionary<Guid, int>>();
|
||||
using var autofacScope = Container.BeginLifetimeScope();
|
||||
var modules = autofacScope.Resolve<IEnumerable<IFeedModule>>();
|
||||
|
||||
foreach (var module in modules)
|
||||
{
|
||||
var result = new List<FeedRow>();
|
||||
var fromTime = feedAggregateDataProvider.GetLastTimeAggregate(module.GetType().Name);
|
||||
if (fromTime == default) fromTime = DateTime.UtcNow.Subtract((TimeSpan)interval);
|
||||
var toTime = DateTime.UtcNow;
|
||||
|
||||
var tenants = Attempt(10, () => module.GetTenantsWithFeeds(fromTime)).ToList();
|
||||
Log.DebugFormat("Find {1} tenants for module {0}.", module.GetType().Name, tenants.Count());
|
||||
|
||||
foreach (var tenant in tenants)
|
||||
{
|
||||
// Warning! There is hack here!
|
||||
// clearing the cache to get the correct acl
|
||||
var cache = AscCache.Memory;
|
||||
cache.Remove("acl" + tenant);
|
||||
cache.Remove("/webitemsecurity/" + tenant);
|
||||
//cache.Remove(string.Format("sub/{0}/{1}/{2}", tenant, "6045b68c-2c2e-42db-9e53-c272e814c4ad", NotifyConstants.Event_NewCommentForMessage.ID));
|
||||
|
||||
try
|
||||
{
|
||||
if (tenantManager.GetTenant(tenant) == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tenantManager.SetCurrentTenant(tenant);
|
||||
var userManager = scope.ServiceProvider.GetService<UserManager>();
|
||||
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
|
||||
var authManager = scope.ServiceProvider.GetService<AuthManager>();
|
||||
var users = userManager.GetUsers();
|
||||
|
||||
var feeds = Attempt(10, () => module.GetFeeds(new FeedFilter(fromTime, toTime) { Tenant = tenant }).Where(r => r.Item1 != null).ToList());
|
||||
Log.DebugFormat("{0} feeds in {1} tenant.", feeds.Count, tenant);
|
||||
|
||||
var tenant1 = tenant;
|
||||
var module1 = module;
|
||||
var feedsRow = feeds
|
||||
.Select(tuple => new Tuple<FeedRow, object>(new FeedRow(tuple.Item1)
|
||||
{
|
||||
Tenant = tenant1,
|
||||
ProductId = module1.Product
|
||||
}, tuple.Item2))
|
||||
.ToList();
|
||||
|
||||
foreach (var u in users)
|
||||
{
|
||||
if (isStopped)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!TryAuthenticate(securityContext, authManager, tenant1, u.ID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
module.VisibleFor(feedsRow, u.ID);
|
||||
}
|
||||
|
||||
result.AddRange(feedsRow.Select(r => r.Item1));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorFormat("Tenant: {0}, {1}", tenant, ex);
|
||||
}
|
||||
}
|
||||
|
||||
feedAggregateDataProvider.SaveFeeds(result, module.GetType().Name, toTime);
|
||||
|
||||
foreach (var res in result)
|
||||
{
|
||||
foreach (var userGuid in res.Users.Where(userGuid => !userGuid.Equals(res.ModifiedById)))
|
||||
{
|
||||
if (!unreadUsers.TryGetValue(res.Tenant, out var dictionary))
|
||||
{
|
||||
dictionary = new Dictionary<Guid, int>();
|
||||
}
|
||||
if (dictionary.ContainsKey(userGuid))
|
||||
{
|
||||
++dictionary[userGuid];
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary.Add(userGuid, 1);
|
||||
}
|
||||
|
||||
unreadUsers[res.Tenant] = dictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//signalrServiceClient.SendUnreadUsers(unreadUsers);
|
||||
|
||||
Log.DebugFormat("Time of collecting news: {0}", DateTime.UtcNow - start);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(aggregateLock);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveFeeds(object interval)
|
||||
{
|
||||
if (!Monitor.TryEnter(removeLock)) return;
|
||||
|
||||
try
|
||||
{
|
||||
using var scope = ServiceProvider.CreateScope();
|
||||
var feedAggregateDataProvider = scope.ServiceProvider.GetService<FeedAggregateDataProvider>();
|
||||
Log.DebugFormat("Start of removing old news");
|
||||
feedAggregateDataProvider.RemoveFeedAggregate(DateTime.UtcNow.Subtract((TimeSpan)interval));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(removeLock);
|
||||
}
|
||||
}
|
||||
|
||||
private static T Attempt<T>(int count, Func<T> action)
|
||||
{
|
||||
var counter = 0;
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (count < ++counter)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryAuthenticate(SecurityContext securityContext, AuthManager authManager, int tenantId, Guid userid)
|
||||
{
|
||||
try
|
||||
{
|
||||
securityContext.AuthenticateMe(authManager.GetAccountByID(tenantId, userid));
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FeedAggregatorServiceExtension
|
||||
{
|
||||
public static DIHelper AddFeedAggregatorService(this DIHelper services)
|
||||
{
|
||||
services.TryAddSingleton<FeedAggregatorService>();
|
||||
|
||||
return services
|
||||
.AddBaseCommonLinkUtilityService()
|
||||
.AddTenantManagerService()
|
||||
.AddUserManagerService()
|
||||
.AddSecurityContextService()
|
||||
.AddAuthManager()
|
||||
.AddFeedAggregateDataProvider();
|
||||
}
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Web.Files.Services.DocumentService;
|
||||
|
||||
namespace ASC.Files.Core
|
||||
@ -303,6 +304,10 @@ namespace ASC.Files.Core
|
||||
|
||||
bool ContainChanges(T fileId, int fileVersion);
|
||||
|
||||
IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to);
|
||||
|
||||
IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -28,6 +28,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
using ASC.Files.Core.Security;
|
||||
|
||||
namespace ASC.Files.Core
|
||||
{
|
||||
public interface IFolderDao<T>
|
||||
@ -292,6 +294,11 @@ namespace ASC.Files.Core
|
||||
/// <returns></returns>
|
||||
Dictionary<string, string> GetBunchObjectIDs(List<T> folderIDs);
|
||||
|
||||
|
||||
IEnumerable<(Folder<T>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to);
|
||||
|
||||
IEnumerable<T> GetTenantsWithFeeds(DateTime fromTime);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ using ASC.Core.Common.Settings;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.ElasticSearch;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Files.Thirdparty.ProviderDao;
|
||||
@ -1204,6 +1205,51 @@ namespace ASC.Files.Core.Data
|
||||
.Any();
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
var q1 = FilesDbContext.Files
|
||||
.Where(r => r.TenantId == tenant)
|
||||
.Where(r => r.CurrentVersion)
|
||||
.Where(r => r.ModifiedOn >= from && r.ModifiedOn <= to);
|
||||
|
||||
var q2 = FromQuery(q1)
|
||||
.Select(r => new DbFileQueryWithSecurity() { DbFileQuery = r, Security = null });
|
||||
|
||||
var q3 = FilesDbContext.Files
|
||||
.Where(r => r.TenantId == tenant)
|
||||
.Where(r => r.CurrentVersion);
|
||||
|
||||
var q4 = FromQuery(q3)
|
||||
.Join(FilesDbContext.Security.DefaultIfEmpty(), r => r.file.Id.ToString(), s => s.EntryId, (f, s) => new DbFileQueryWithSecurity { DbFileQuery = f, Security = s })
|
||||
.Where(r => r.Security.TenantId == tenant)
|
||||
.Where(r => r.Security.EntryType == FileEntryType.File)
|
||||
.Where(r => r.Security.Security == Security.FileShare.Restrict)
|
||||
.Where(r => r.Security.TimeStamp >= from && r.Security.TimeStamp <= to);
|
||||
|
||||
return q2.Select(ToFileWithShare).ToList().Union(q4.Select(ToFileWithShare).ToList());
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
var q1 = FilesDbContext.Files
|
||||
.Where(r => r.ModifiedOn > fromTime)
|
||||
.Select(r => r.TenantId)
|
||||
.GroupBy(r => r)
|
||||
.Where(r => r.Count() > 0)
|
||||
.Select(r => r.Key)
|
||||
.ToList();
|
||||
|
||||
var q2 = FilesDbContext.Security
|
||||
.Where(r => r.TimeStamp > fromTime)
|
||||
.Select(r => r.TenantId)
|
||||
.GroupBy(r => r)
|
||||
.Where(r => r.Count() > 0)
|
||||
.Select(r => r.Key)
|
||||
.ToList();
|
||||
|
||||
return q1.Union(q2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Func<Selector<DbFile>, Selector<DbFile>> GetFuncForSearch(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false)
|
||||
@ -1341,6 +1387,21 @@ namespace ASC.Files.Core.Data
|
||||
return file;
|
||||
}
|
||||
|
||||
public (File<int>, SmallShareRecord) ToFileWithShare(DbFileQueryWithSecurity r)
|
||||
{
|
||||
var file = ToFile(r.DbFileQuery);
|
||||
var record = r.Security != null
|
||||
? new SmallShareRecord
|
||||
{
|
||||
ShareOn = r.Security.TimeStamp,
|
||||
ShareBy = r.Security.Owner,
|
||||
ShareTo = r.Security.Subject
|
||||
}
|
||||
: null;
|
||||
|
||||
return (file, record);
|
||||
}
|
||||
|
||||
internal protected DbFile InitDocument(DbFile dbFile)
|
||||
{
|
||||
if (!FactoryIndexer.CanSearchByContent())
|
||||
@ -1379,6 +1440,12 @@ namespace ASC.Files.Core.Data
|
||||
public bool shared { get; set; }
|
||||
}
|
||||
|
||||
public class DbFileQueryWithSecurity
|
||||
{
|
||||
public DbFileQuery DbFileQuery { get; set; }
|
||||
public DbFilesSecurity Security { get; set; }
|
||||
}
|
||||
|
||||
public static class FileDaoExtention
|
||||
{
|
||||
public static DIHelper AddFileDaoService(this DIHelper services)
|
||||
|
@ -37,6 +37,7 @@ using ASC.Core.Common.Settings;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.ElasticSearch;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Files.Thirdparty.ProviderDao;
|
||||
@ -1081,6 +1082,21 @@ namespace ASC.Files.Core.Data
|
||||
return result;
|
||||
}
|
||||
|
||||
public (Folder<int>, SmallShareRecord) ToFolderWithShare(DbFolderQueryWithSecurity r)
|
||||
{
|
||||
var file = ToFolder(r.DbFolderQuery);
|
||||
var record = r.Security != null
|
||||
? new SmallShareRecord
|
||||
{
|
||||
ShareOn = r.Security.TimeStamp,
|
||||
ShareBy = r.Security.Owner,
|
||||
ShareTo = r.Security.Subject
|
||||
}
|
||||
: null;
|
||||
|
||||
return (file, record);
|
||||
}
|
||||
|
||||
public string GetBunchObjectID(int folderID)
|
||||
{
|
||||
return Query(FilesDbContext.BunchObjects)
|
||||
@ -1096,6 +1112,51 @@ namespace ASC.Files.Core.Data
|
||||
.ToDictionary(r => r.LeftNode, r => r.RightNode);
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
var q1 = FilesDbContext.Folders
|
||||
.Where(r => r.TenantId == tenant)
|
||||
.Where(r => r.FolderType == FolderType.DEFAULT)
|
||||
.Where(r => r.CreateOn >= from && r.ModifiedOn <= to);
|
||||
|
||||
var q2 = FromQuery(q1)
|
||||
.Select(r => new DbFolderQueryWithSecurity() { DbFolderQuery = r, Security = null });
|
||||
|
||||
var q3 = FilesDbContext.Folders
|
||||
.Where(r => r.TenantId == tenant)
|
||||
.Where(r => r.FolderType == FolderType.DEFAULT);
|
||||
|
||||
var q4 = FromQuery(q3)
|
||||
.Join(FilesDbContext.Security.DefaultIfEmpty(), r => r.folder.Id.ToString(), s => s.EntryId, (f, s) => new DbFolderQueryWithSecurity { DbFolderQuery = f, Security = s })
|
||||
.Where(r => r.Security.TenantId == tenant)
|
||||
.Where(r => r.Security.EntryType == FileEntryType.Folder)
|
||||
.Where(r => r.Security.Security == FileShare.Restrict)
|
||||
.Where(r => r.Security.TimeStamp >= from && r.Security.TimeStamp <= to);
|
||||
|
||||
return q2.Select(ToFolderWithShare).ToList().Union(q4.Select(ToFolderWithShare).ToList());
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
var q1 = FilesDbContext.Files
|
||||
.Where(r => r.ModifiedOn > fromTime)
|
||||
.Select(r => r.TenantId)
|
||||
.GroupBy(r => r)
|
||||
.Where(r => r.Count() > 0)
|
||||
.Select(r => r.Key)
|
||||
.ToList();
|
||||
|
||||
var q2 = FilesDbContext.Security
|
||||
.Where(r => r.TimeStamp > fromTime)
|
||||
.Select(r => r.TenantId)
|
||||
.GroupBy(r => r)
|
||||
.Where(r => r.Count() > 0)
|
||||
.Select(r => r.Key)
|
||||
.ToList();
|
||||
|
||||
return q1.Union(q2);
|
||||
}
|
||||
|
||||
private string GetProjectTitle(object folderID)
|
||||
{
|
||||
return "";
|
||||
@ -1159,6 +1220,12 @@ namespace ASC.Files.Core.Data
|
||||
public bool shared { get; set; }
|
||||
}
|
||||
|
||||
public class DbFolderQueryWithSecurity
|
||||
{
|
||||
public DbFolderQuery DbFolderQuery { get; set; }
|
||||
public DbFilesSecurity Security { get; set; }
|
||||
}
|
||||
|
||||
public static class FolderDaoExtention
|
||||
{
|
||||
public static DIHelper AddFolderDaoService(this DIHelper services)
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -538,7 +539,7 @@ namespace ASC.Files.Thirdparty.Box
|
||||
if (uploadSession.BytesUploaded == uploadSession.BytesTotal)
|
||||
{
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"),
|
||||
FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
FileMode.Open, FileAccess.Read, System.IO.FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
{
|
||||
uploadSession.File = SaveFile(uploadSession.File, fs);
|
||||
}
|
||||
@ -606,6 +607,16 @@ namespace ASC.Files.Thirdparty.Box
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Studio.Core;
|
||||
@ -510,6 +511,16 @@ namespace ASC.Files.Thirdparty.Box
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<string>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -590,7 +591,7 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
}
|
||||
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"),
|
||||
FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
FileMode.Open, FileAccess.Read, System.IO.FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
{
|
||||
return SaveFile(uploadSession.File, fs);
|
||||
}
|
||||
@ -653,6 +654,16 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Studio.Core;
|
||||
@ -507,6 +508,16 @@ namespace ASC.Files.Thirdparty.Dropbox
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<string>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -582,7 +583,7 @@ namespace ASC.Files.Thirdparty.GoogleDrive
|
||||
return ToFile(GetDriveEntry(googleDriveSession.FileId));
|
||||
}
|
||||
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"), FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"), FileMode.Open, FileAccess.Read, System.IO.FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
{
|
||||
return SaveFile(uploadSession.File, fs);
|
||||
}
|
||||
@ -654,6 +655,16 @@ namespace ASC.Files.Thirdparty.GoogleDrive
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Studio.Core;
|
||||
@ -499,6 +500,16 @@ namespace ASC.Files.Thirdparty.GoogleDrive
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<string>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -581,7 +582,7 @@ namespace ASC.Files.Thirdparty.OneDrive
|
||||
return ToFile(GetOneDriveItem(oneDriveSession.FileId));
|
||||
}
|
||||
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"), FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"), FileMode.Open, FileAccess.Read, System.IO.FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
{
|
||||
return SaveFile(uploadSession.File, fs);
|
||||
}
|
||||
@ -655,6 +656,16 @@ namespace ASC.Files.Thirdparty.OneDrive
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Studio.Core;
|
||||
@ -510,6 +511,16 @@ namespace ASC.Files.Thirdparty.OneDrive
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<string>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ using ASC.Common;
|
||||
using ASC.Core;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.Data;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Web.Files.Services.DocumentService;
|
||||
|
||||
@ -509,6 +510,16 @@ namespace ASC.Files.Thirdparty.ProviderDao
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ using ASC.Common;
|
||||
using ASC.Core;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.Data;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
|
||||
namespace ASC.Files.Thirdparty.ProviderDao
|
||||
@ -411,6 +412,16 @@ filterType, subjectGroup, subjectID, searchText, searchSubfolders, checkShare);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<string>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -484,6 +485,16 @@ namespace ASC.Files.Thirdparty.SharePoint
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Studio.Core;
|
||||
@ -466,6 +467,16 @@ namespace ASC.Files.Thirdparty.SharePoint
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<string>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -261,7 +262,7 @@ namespace ASC.Files.Thirdparty.Sharpbox
|
||||
{
|
||||
if (!fileStream.CanSeek)
|
||||
{
|
||||
var tempBuffer = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 8096, FileOptions.DeleteOnClose);
|
||||
var tempBuffer = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite, System.IO.FileShare.Read, 8096, FileOptions.DeleteOnClose);
|
||||
|
||||
fileStream.CopyTo(tempBuffer);
|
||||
tempBuffer.Flush();
|
||||
@ -625,7 +626,7 @@ namespace ASC.Files.Thirdparty.Sharpbox
|
||||
return ToFile(GetFileById(sharpboxSession.FileId));
|
||||
}
|
||||
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"), FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
using (var fs = new FileStream(uploadSession.GetItemOrDefault<string>("TempPath"), FileMode.Open, FileAccess.Read, System.IO.FileShare.None, 4096, FileOptions.DeleteOnClose))
|
||||
{
|
||||
return SaveFile(uploadSession.File, fs);
|
||||
}
|
||||
@ -710,6 +711,16 @@ namespace ASC.Files.Thirdparty.Sharpbox
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<(File<int>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ using ASC.Core.Common.EF;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Files.Core.Thirdparty;
|
||||
using ASC.Files.Resources;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -530,6 +531,16 @@ namespace ASC.Files.Thirdparty.Sharpbox
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<(Folder<string>, SmallShareRecord)> GetFeeds(int tenant, DateTime from, DateTime to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
<ProjectReference Include="..\..\..\common\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\services\ASC.ElasticSearch\ASC.ElasticSearch.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\services\ASC.Feed.Aggregator\ASC.Feed.Aggregator.csproj" />
|
||||
<ProjectReference Include="..\Server\ASC.Files.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
194
products/ASC.Files/Service/Core/FilesModule.cs
Normal file
194
products/ASC.Files/Service/Core/FilesModule.cs
Normal file
@ -0,0 +1,194 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using ASC.Core;
|
||||
using ASC.Feed;
|
||||
using ASC.Feed.Data;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Web.Core;
|
||||
using ASC.Web.Core.Files;
|
||||
|
||||
using FeedModule = ASC.Feed.Aggregator.Modules.FeedModule;
|
||||
|
||||
namespace ASC.Files.Service.Core
|
||||
{
|
||||
public class FilesModule : FeedModule
|
||||
{
|
||||
private const string fileItem = "file";
|
||||
private const string sharedFileItem = "sharedFile";
|
||||
|
||||
public override string Name => Constants.FilesModule;
|
||||
|
||||
public override string Product => "documents";
|
||||
|
||||
public override Guid ProductID => WebItemManager.DocumentsProductID;
|
||||
|
||||
protected override string DbId => "files";
|
||||
|
||||
public IFileDao<int> FileDao { get; }
|
||||
public IFolderDao<int> FolderDao { get; }
|
||||
public UserManager UserManager { get; }
|
||||
public FilesLinkUtility FilesLinkUtility { get; }
|
||||
public FileSecurity FileSecurity { get; }
|
||||
|
||||
public FilesModule(
|
||||
TenantManager tenantManager,
|
||||
UserManager userManager,
|
||||
WebItemSecurity webItemSecurity,
|
||||
FilesLinkUtility filesLinkUtility,
|
||||
FileSecurity fileSecurity,
|
||||
IDaoFactory daoFactory)
|
||||
: base(tenantManager, webItemSecurity)
|
||||
{
|
||||
FileDao = daoFactory.GetFileDao<int>();
|
||||
FolderDao = daoFactory.GetFolderDao<int>();
|
||||
UserManager = userManager;
|
||||
FilesLinkUtility = filesLinkUtility;
|
||||
FileSecurity = fileSecurity;
|
||||
}
|
||||
|
||||
public override bool VisibleFor(Feed.Aggregator.Feed feed, object data, Guid userId)
|
||||
{
|
||||
if (!WebItemSecurity.IsAvailableForUser(ProductID, userId)) return false;
|
||||
|
||||
var tuple = ((File<int>, SmallShareRecord))data;
|
||||
var file = tuple.Item1;
|
||||
var shareRecord = tuple.Item2;
|
||||
|
||||
bool targetCond;
|
||||
if (feed.Target != null)
|
||||
{
|
||||
if (shareRecord != null && shareRecord.ShareBy == userId) return false;
|
||||
|
||||
var owner = (Guid)feed.Target;
|
||||
var groupUsers = UserManager.GetUsersByGroup(owner).Select(x => x.ID).ToList();
|
||||
if (!groupUsers.Any())
|
||||
{
|
||||
groupUsers.Add(owner);
|
||||
}
|
||||
targetCond = groupUsers.Contains(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetCond = true;
|
||||
}
|
||||
|
||||
return targetCond && FileSecurity.CanRead(file, userId);
|
||||
}
|
||||
|
||||
public override void VisibleFor(List<Tuple<FeedRow, object>> feed, Guid userId)
|
||||
{
|
||||
if (!WebItemSecurity.IsAvailableForUser(ProductID, userId)) return;
|
||||
|
||||
var feed1 = feed.Select(r =>
|
||||
{
|
||||
var tuple = ((File<int>, SmallShareRecord))r.Item2;
|
||||
return new Tuple<FeedRow, File<int>, SmallShareRecord>(r.Item1, tuple.Item1, tuple.Item2);
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var files = feed1.Where(r => r.Item1.Feed.Target == null).Select(r => r.Item2).ToList();
|
||||
|
||||
foreach (var f in feed1.Where(r => r.Item1.Feed.Target != null && !(r.Item3 != null && r.Item3.ShareBy == userId)))
|
||||
{
|
||||
var file = f.Item2;
|
||||
if (IsTarget(f.Item1.Feed.Target, userId) && !files.Any(r => r.UniqID.Equals(file.UniqID)))
|
||||
{
|
||||
files.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
var canRead = FileSecurity.CanRead(files, userId).Where(r => r.Item2).ToList();
|
||||
|
||||
foreach (var f in feed1)
|
||||
{
|
||||
if (IsTarget(f.Item1.Feed.Target, userId) && canRead.Any(r => r.Item1.ID.Equals(f.Item2.ID)))
|
||||
{
|
||||
f.Item1.Users.Add(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<Tuple<Feed.Aggregator.Feed, object>> GetFeeds(FeedFilter filter)
|
||||
{
|
||||
var files = FileDao.GetFeeds(filter.Tenant, filter.Time.From, filter.Time.To)
|
||||
.Where(f => f.Item1.RootFolderType != FolderType.TRASH && f.Item1.RootFolderType != FolderType.BUNCH)
|
||||
.ToList();
|
||||
|
||||
var folderIDs = files.Select(r => r.Item1.FolderID).ToArray();
|
||||
var folders = FolderDao.GetFolders(folderIDs, checkShare: false);
|
||||
|
||||
return files.Select(f => new Tuple<Feed.Aggregator.Feed, object>(ToFeed(f, folders.FirstOrDefault(r => r.ID.Equals(f.Item1.FolderID))), f));
|
||||
}
|
||||
|
||||
public override IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
return FileDao.GetTenantsWithFeeds(fromTime);
|
||||
}
|
||||
|
||||
private Feed.Aggregator.Feed ToFeed((File<int>, SmallShareRecord) tuple, Folder<int> rootFolder)
|
||||
{
|
||||
var file = tuple.Item1;
|
||||
var shareRecord = tuple.Item2;
|
||||
|
||||
if (shareRecord != null)
|
||||
{
|
||||
var feed = new Feed.Aggregator.Feed(shareRecord.ShareBy, shareRecord.ShareOn, true)
|
||||
{
|
||||
Item = sharedFileItem,
|
||||
ItemId = string.Format("{0}_{1}", file.ID, shareRecord.ShareTo),
|
||||
ItemUrl = FilesLinkUtility.GetFileRedirectPreviewUrl(file.ID, true),
|
||||
Product = Product,
|
||||
Module = Name,
|
||||
Title = file.Title,
|
||||
ExtraLocation = rootFolder.FolderType == FolderType.DEFAULT ? rootFolder.Title : string.Empty,
|
||||
ExtraLocationUrl = rootFolder.FolderType == FolderType.DEFAULT ? FilesLinkUtility.GetFileRedirectPreviewUrl(file.FolderID, false) : string.Empty,
|
||||
AdditionalInfo = file.ContentLengthString,
|
||||
Keywords = string.Format("{0}", file.Title),
|
||||
HasPreview = false,
|
||||
CanComment = false,
|
||||
Target = shareRecord.ShareTo,
|
||||
GroupId = GetGroupId(sharedFileItem, shareRecord.ShareBy, file.FolderID.ToString())
|
||||
};
|
||||
|
||||
return feed;
|
||||
}
|
||||
|
||||
var updated = file.Version != 1;
|
||||
return new Feed.Aggregator.Feed(file.ModifiedBy, file.ModifiedOn, true)
|
||||
{
|
||||
Item = fileItem,
|
||||
ItemId = string.Format("{0}_{1}", file.ID, file.Version > 1 ? 1 : 0),
|
||||
ItemUrl = FilesLinkUtility.GetFileRedirectPreviewUrl(file.ID, true),
|
||||
Product = Product,
|
||||
Module = Name,
|
||||
Action = updated ? FeedAction.Updated : FeedAction.Created,
|
||||
Title = file.Title,
|
||||
ExtraLocation = rootFolder.FolderType == FolderType.DEFAULT ? rootFolder.Title : string.Empty,
|
||||
ExtraLocationUrl = rootFolder.FolderType == FolderType.DEFAULT ? FilesLinkUtility.GetFileRedirectPreviewUrl(file.FolderID, false) : string.Empty,
|
||||
AdditionalInfo = file.ContentLengthString,
|
||||
Keywords = string.Format("{0}", file.Title),
|
||||
HasPreview = false,
|
||||
CanComment = false,
|
||||
Target = null,
|
||||
GroupId = GetGroupId(fileItem, file.ModifiedBy, file.FolderID.ToString(), updated ? 1 : 0)
|
||||
};
|
||||
}
|
||||
|
||||
private bool IsTarget(object target, Guid userId)
|
||||
{
|
||||
if (target == null) return true;
|
||||
var owner = (Guid)target;
|
||||
var groupUsers = UserManager.GetUsersByGroup(owner).Select(x => x.ID).ToList();
|
||||
if (!groupUsers.Any())
|
||||
{
|
||||
groupUsers.Add(owner);
|
||||
}
|
||||
|
||||
return groupUsers.Contains(userId);
|
||||
}
|
||||
}
|
||||
}
|
143
products/ASC.Files/Service/Core/FoldersModule.cs
Normal file
143
products/ASC.Files/Service/Core/FoldersModule.cs
Normal file
@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using ASC.Core;
|
||||
using ASC.Feed;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.Security;
|
||||
using ASC.Web.Core;
|
||||
using ASC.Web.Core.Files;
|
||||
|
||||
using FeedModule = ASC.Feed.Aggregator.Modules.FeedModule;
|
||||
|
||||
namespace ASC.Files.Service.Core
|
||||
{
|
||||
public class FoldersModule : FeedModule
|
||||
{
|
||||
private const string folderItem = "folder";
|
||||
private const string sharedFolderItem = "sharedFolder";
|
||||
|
||||
protected override string DbId => Constants.FilesDbId;
|
||||
|
||||
public override string Name => Constants.FoldersModule;
|
||||
|
||||
public override string Product => "documents";
|
||||
|
||||
public override Guid ProductID => WebItemManager.DocumentsProductID;
|
||||
|
||||
public UserManager UserManager { get; }
|
||||
public FilesLinkUtility FilesLinkUtility { get; }
|
||||
public FileSecurity FileSecurity { get; }
|
||||
|
||||
public IFileDao<int> FileDao { get; }
|
||||
public IFolderDao<int> FolderDao { get; }
|
||||
|
||||
public FoldersModule(
|
||||
TenantManager tenantManager,
|
||||
UserManager userManager,
|
||||
WebItemSecurity webItemSecurity,
|
||||
FilesLinkUtility filesLinkUtility,
|
||||
FileSecurity fileSecurity,
|
||||
IDaoFactory daoFactory)
|
||||
: base(tenantManager, webItemSecurity)
|
||||
{
|
||||
UserManager = userManager;
|
||||
FilesLinkUtility = filesLinkUtility;
|
||||
FileSecurity = fileSecurity;
|
||||
FileDao = daoFactory.GetFileDao<int>();
|
||||
FolderDao = daoFactory.GetFolderDao<int>();
|
||||
}
|
||||
|
||||
public override bool VisibleFor(Feed.Aggregator.Feed feed, object data, Guid userId)
|
||||
{
|
||||
if (!WebItemSecurity.IsAvailableForUser(ProductID, userId)) return false;
|
||||
|
||||
var tuple = (Tuple<Folder<int>, SmallShareRecord>)data;
|
||||
var folder = tuple.Item1;
|
||||
var shareRecord = tuple.Item2;
|
||||
|
||||
bool targetCond;
|
||||
if (feed.Target != null)
|
||||
{
|
||||
if (shareRecord != null && shareRecord.ShareBy == userId) return false;
|
||||
|
||||
var owner = (Guid)feed.Target;
|
||||
var groupUsers = UserManager.GetUsersByGroup(owner).Select(x => x.ID).ToList();
|
||||
if (!groupUsers.Any())
|
||||
{
|
||||
groupUsers.Add(owner);
|
||||
}
|
||||
targetCond = groupUsers.Contains(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetCond = true;
|
||||
}
|
||||
|
||||
return targetCond && FileSecurity.CanRead(folder, userId);
|
||||
}
|
||||
|
||||
public override IEnumerable<int> GetTenantsWithFeeds(DateTime fromTime)
|
||||
{
|
||||
return FolderDao.GetTenantsWithFeeds(fromTime);
|
||||
}
|
||||
|
||||
public override IEnumerable<Tuple<Feed.Aggregator.Feed, object>> GetFeeds(FeedFilter filter)
|
||||
{
|
||||
var folders = FolderDao.GetFeeds(filter.Tenant, filter.Time.From, filter.Time.To)
|
||||
.Where(f => f.Item1.RootFolderType != FolderType.TRASH && f.Item1.RootFolderType != FolderType.BUNCH)
|
||||
.ToList();
|
||||
|
||||
var parentFolderIDs = folders.Select(r => r.Item1.ParentFolderID).ToArray();
|
||||
var parentFolders = FolderDao.GetFolders(parentFolderIDs, checkShare: false);
|
||||
|
||||
return folders.Select(f => new Tuple<Feed.Aggregator.Feed, object>(ToFeed(f, parentFolders.FirstOrDefault(r => r.ID.Equals(f.Item1.ParentFolderID))), f));
|
||||
}
|
||||
|
||||
private Feed.Aggregator.Feed ToFeed((Folder<int>, SmallShareRecord) tuple, Folder<int> rootFolder)
|
||||
{
|
||||
var folder = tuple.Item1;
|
||||
var shareRecord = tuple.Item2;
|
||||
|
||||
if (shareRecord != null)
|
||||
{
|
||||
var feed = new Feed.Aggregator.Feed(shareRecord.ShareBy, shareRecord.ShareOn, true)
|
||||
{
|
||||
Item = sharedFolderItem,
|
||||
ItemId = string.Format("{0}_{1}", folder.ID, shareRecord.ShareTo),
|
||||
ItemUrl = FilesLinkUtility.GetFileRedirectPreviewUrl(folder.ID, false),
|
||||
Product = Product,
|
||||
Module = Name,
|
||||
Title = folder.Title,
|
||||
ExtraLocation = rootFolder.FolderType == FolderType.DEFAULT ? rootFolder.Title : string.Empty,
|
||||
ExtraLocationUrl = rootFolder.FolderType == FolderType.DEFAULT ? FilesLinkUtility.GetFileRedirectPreviewUrl(folder.ParentFolderID, false) : string.Empty,
|
||||
Keywords = string.Format("{0}", folder.Title),
|
||||
HasPreview = false,
|
||||
CanComment = false,
|
||||
Target = shareRecord.ShareTo,
|
||||
GroupId = GetGroupId(sharedFolderItem, shareRecord.ShareBy, folder.ParentFolderID.ToString())
|
||||
};
|
||||
|
||||
return feed;
|
||||
}
|
||||
|
||||
return new Feed.Aggregator.Feed(folder.CreateBy, folder.CreateOn)
|
||||
{
|
||||
Item = folderItem,
|
||||
ItemId = folder.ID.ToString(),
|
||||
ItemUrl = FilesLinkUtility.GetFileRedirectPreviewUrl(folder.ID, false),
|
||||
Product = Product,
|
||||
Module = Name,
|
||||
Title = folder.Title,
|
||||
ExtraLocation = rootFolder.FolderType == FolderType.DEFAULT ? rootFolder.Title : string.Empty,
|
||||
ExtraLocationUrl = rootFolder.FolderType == FolderType.DEFAULT ? FilesLinkUtility.GetFileRedirectPreviewUrl(folder.ParentFolderID, false) : string.Empty,
|
||||
Keywords = string.Format("{0}", folder.Title),
|
||||
HasPreview = false,
|
||||
CanComment = false,
|
||||
Target = null,
|
||||
GroupId = GetGroupId(folderItem, folder.CreateBy, folder.ParentFolderID.ToString())
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.ElasticSearch;
|
||||
using ASC.Feed.Aggregator;
|
||||
using ASC.Web.Files.Core.Search;
|
||||
using ASC.Web.Files.Utils;
|
||||
|
||||
@ -39,6 +40,7 @@ namespace ASC.Files.Service
|
||||
)
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddJsonFile($"appsettings.{env}.json", true)
|
||||
.AddJsonFile($"appsettings.services.json", true)
|
||||
.AddJsonFile("storage.json")
|
||||
.AddJsonFile("notify.json")
|
||||
.AddJsonFile("kafka.json")
|
||||
@ -58,8 +60,12 @@ namespace ASC.Files.Service
|
||||
.AddFactoryIndexerFileService()
|
||||
.AddFactoryIndexerFolderService();
|
||||
|
||||
var a = typeof(FactoryIndexer<ISearchItem>).ToString();
|
||||
services.AddAutofac(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath, false, false, "search.json");
|
||||
diHelper.AddNLogManager("ASC.Feed.Agregator");
|
||||
services.AddHostedService<FeedAggregatorService>();
|
||||
diHelper
|
||||
.AddFeedAggregatorService();
|
||||
|
||||
services.AddAutofac(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath, true, false, "search.json", "feed.json");
|
||||
})
|
||||
.UseConsoleLifetime()
|
||||
.Build();
|
||||
|
22
products/ASC.Files/Service/feed.json
Normal file
22
products/ASC.Files/Service/feed.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"type": "ASC.Files.Service.Core.FilesModule, ASC.Files.Service",
|
||||
"services": [
|
||||
{
|
||||
"type": "ASC.Feed.Aggregator.Modules.IFeedModule, ASC.Feed.Aggregator"
|
||||
}
|
||||
],
|
||||
"instanceScope": "perlifetimescope"
|
||||
},
|
||||
{
|
||||
"type": "ASC.Files.Service.Core.FoldersModule, ASC.Files.Service",
|
||||
"services": [
|
||||
{
|
||||
"type": "ASC.Feed.Aggregator.Modules.IFeedModule, ASC.Feed.Aggregator"
|
||||
}
|
||||
],
|
||||
"instanceScope": "perlifetimescope"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user