1176 lines
36 KiB
C#
1176 lines
36 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using xCommons.Extensions;
|
|
using xDataService.Configuration;
|
|
using xDataService.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityService.Extensions;
|
|
using xIdentityService.Interfaces;
|
|
using xModels.Dtos;
|
|
using xPushService.Constants;
|
|
using xWebinarService.Constants;
|
|
using xWebinarService.Hubs;
|
|
using xWebinarService.Interfaces;
|
|
using xWebinarService.Interfaces.Entities;
|
|
using xWebinarService.Models.Dtos;
|
|
using xWebinarService.Models.Entities;
|
|
|
|
namespace xWebinarService.Providers
|
|
{
|
|
/// <summary>
|
|
/// Implement all Webinar Related Things here ...
|
|
/// </summary>
|
|
public class XWebinarProvider : IXWebinarProvider
|
|
{
|
|
//
|
|
#region Props ...
|
|
public IHubContext<XWebinarEntityHub> Hub { get; }
|
|
public IXIdentityProvider IdentityProvider { get; }
|
|
public IXWebinarRepository WebinarRepository { get; }
|
|
public XDataServiceConfiguration DataSercviceConfiguration { get; }
|
|
public IXWebinarTitleResourceProvider TitleResourceProvider { get; }
|
|
public IXWebinarSubscriberRepository WebinarSubscriberRepository { get; }
|
|
public IXWebinarDescriptionResourceProvider DescriptionResourceProvider { get; }
|
|
#endregion
|
|
|
|
//
|
|
#region Constructor ...
|
|
public XWebinarProvider(
|
|
IXIdentityProvider identityProvider,
|
|
IXWebinarRepository webinarRepository,
|
|
XDataServiceConfiguration dataSercviceConfiguration,
|
|
IXWebinarTitleResourceProvider titleResourceProvider,
|
|
IXWebinarSubscriberRepository webinarSubscriberRepository,
|
|
IXWebinarDescriptionResourceProvider descriptionResourceProvider,
|
|
IHubContext<XWebinarEntityHub> hub = null
|
|
)
|
|
{
|
|
//
|
|
IdentityProvider = identityProvider;
|
|
WebinarRepository = webinarRepository;
|
|
DataSercviceConfiguration = dataSercviceConfiguration;
|
|
TitleResourceProvider = titleResourceProvider;
|
|
WebinarSubscriberRepository = webinarSubscriberRepository;
|
|
DescriptionResourceProvider = descriptionResourceProvider;
|
|
Hub = hub;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Tools ...
|
|
/// <summary>
|
|
/// Converts Specified XWebinar Entity to it's Corresponding Dto Presentation
|
|
/// and also Fill Owner and Title/Description Resources ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <returns></returns>
|
|
public async Task<XWebinarDto> ToXWebinarDto(XWebinar model)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!model.IsNullOrDefault() &&
|
|
!model.Title.IsNullOrEmpty() &&
|
|
!model.OwnerId.IsNullOrEmpty() &&
|
|
!model.Description.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var result = new XWebinarDto
|
|
{
|
|
//
|
|
// Set Common Properties ...
|
|
Id = model.Id,
|
|
Type = model.Type,
|
|
OwnerId = model.OwnerId,
|
|
Enabled = model.Enabled,
|
|
CreatedOn = model.CreatedOn,
|
|
|
|
//
|
|
// Fill Resources ...
|
|
Title = await TitleResourceProvider.GetResource(model.Id.ToString()),
|
|
Description = await DescriptionResourceProvider.GetResource(model.Id.ToString())
|
|
};
|
|
|
|
//
|
|
// Prepare Inner API Providers Device Dto ...
|
|
var device = IdentityProvider.GetDevice();
|
|
var userInfo = await IdentityProvider.GetUserInfo(
|
|
device: device,
|
|
userSelectByParam: model.OwnerId
|
|
);
|
|
isValid = !userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
result.Owner = userInfo.ToXPersonDto();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts Specified WebinarSubscriber Entity to it's Dto Presentation ...
|
|
/// </summary>
|
|
/// <param name="model"></param>
|
|
/// <returns></returns>
|
|
public async Task<XWebinarSubscriberDto> ToXWebinarSubscriberDto(XWebinarSubscriber model)
|
|
{
|
|
//
|
|
bool isValid =
|
|
!model.IsNull() &&
|
|
!model.SubscriberId.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve User Info ...
|
|
var device = IdentityProvider.GetDevice();
|
|
var userInfo = await IdentityProvider.GetUserInfo(
|
|
device: device,
|
|
userSelectByParam: model.SubscriberId
|
|
);
|
|
isValid = !userInfo.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = new XWebinarSubscriberDto
|
|
{
|
|
Id = model.Id,
|
|
WebinarId = model.WebinarId,
|
|
SubscriberId = model.SubscriberId,
|
|
SubscribedOn = model.SubscribedOn,
|
|
Subscriber = userInfo.ToXPersonDto(),
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Actions ...
|
|
/// <summary>
|
|
/// Create Webinar ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <returns></returns>
|
|
public async Task<XWebinarDto> CreateWebinar(
|
|
XWebinarDto item,
|
|
string connectionId = null
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!item.IsNull() &&
|
|
!item.Title.IsNull() &&
|
|
!item.Description.IsNull() &&
|
|
!item.OwnerId.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Title and Descriptions Has Value ...
|
|
isValid =
|
|
item.Title.Locales.HasChild() &&
|
|
item.Description.Locales.HasChild() &&
|
|
item.Title.Locales.All(l => !l.Value.IsNullOrEmpty()) &&
|
|
item.Description.Locales.All(l => !l.Value.IsNullOrEmpty());
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Temp Webinar Entity ...
|
|
string tmpValue = Guid.NewGuid().ToString();
|
|
var entity = new XWebinar
|
|
{
|
|
Type = item.Type,
|
|
OwnerId = item.OwnerId,
|
|
Title = "T_" + tmpValue,
|
|
CreatedOn = DateTime.UtcNow,
|
|
Description = "D_" + tmpValue,
|
|
};
|
|
entity = await WebinarRepository.AddAsync(entity);
|
|
isValid =
|
|
!entity.IsNullOrDefault() &&
|
|
!entity.Id.IsDefaultGuid();
|
|
if (!isValid)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Use Entity ID as Resources Suffix ...
|
|
Guid suffixGuid = entity.Id;
|
|
string suffix = suffixGuid.ToString();
|
|
var titleResource = await TitleResourceProvider.AddResource(
|
|
suffix: suffix,
|
|
item: item.Title
|
|
);
|
|
var descriptionResource = await DescriptionResourceProvider.AddResource(
|
|
suffix: suffix,
|
|
item: item.Description
|
|
);
|
|
isValid =
|
|
//
|
|
// Title Resource Validation ...
|
|
!titleResource.IsNullOrDefault() &&
|
|
titleResource.Locales.HasChild() &&
|
|
!titleResource.Resource.IsNullOrEmpty() &&
|
|
//
|
|
// Description Resource Validation ...
|
|
!descriptionResource.IsNullOrDefault() &&
|
|
descriptionResource.Locales.HasChild() &&
|
|
!descriptionResource.Resource.IsNullOrEmpty()
|
|
;
|
|
if (!isValid)
|
|
{
|
|
//
|
|
// Rollback ...
|
|
try
|
|
{
|
|
//
|
|
entity.Id = suffixGuid;
|
|
await TitleResourceProvider.Remove(suffix);
|
|
await WebinarRepository.RemoveAsync(entity);
|
|
await DescriptionResourceProvider.Remove(suffix);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Update Title/Description Resources ...
|
|
entity.Title = titleResource.Resource;
|
|
entity.Description = descriptionResource.Resource;
|
|
entity = await WebinarRepository.UpdateAsync(entity.Id, entity);
|
|
isValid = !entity.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
//
|
|
// Rollback ...
|
|
try
|
|
{
|
|
//
|
|
entity.Id = suffixGuid;
|
|
await TitleResourceProvider.Remove(suffix);
|
|
await WebinarRepository.RemoveAsync(entity);
|
|
await DescriptionResourceProvider.Remove(suffix);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
await SendPush(
|
|
action: XBaseEntityHubAction.Add.GetStringValue(),
|
|
payLoad: entity.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
|
|
//
|
|
// Convert Entity to Dto ...
|
|
var result = await ToXWebinarDto(entity);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a Webinar ...
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <returns></returns>
|
|
public async Task<XWebinarDto> UpdateWebinar(
|
|
XWebinarDto item,
|
|
string connectionId = null
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!item.Id.IsNull() &&
|
|
|
|
!item.IsNullOrDefault() &&
|
|
!item.Id.IsDefaultGuid() &&
|
|
!item.OwnerId.IsNullOrEmpty() &&
|
|
!item.Title.IsNullOrDefault() &&
|
|
!item.Description.IsNullOrDefault() &&
|
|
//
|
|
// Title Validation ...
|
|
item.Title.Locales.HasChild() &&
|
|
!item.Title.Resource.IsNullOrEmpty() &&
|
|
item.Title.Locales.All(l => !l.IsNullOrDefault() && !l.Value.IsNullOrEmpty() && !l.Language.IsNullOrEmpty()) &&
|
|
//
|
|
// Description Validation ...
|
|
item.Description.Locales.HasChild() &&
|
|
!item.Description.Resource.IsNullOrEmpty() &&
|
|
item.Description.Locales.All(l => !l.IsNullOrDefault() && !l.Value.IsNullOrEmpty() && !l.Language.IsNullOrEmpty())
|
|
;
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Item Exists ...
|
|
isValid = await WebinarRepository.IsExistsAsync(item.Id);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Entity ...
|
|
var entity = await WebinarRepository.GetAsync(item.Id);
|
|
|
|
//
|
|
// Check if Type Change Update it ...
|
|
if (entity.Type != item.Type)
|
|
{
|
|
//
|
|
entity.Type = item.Type;
|
|
entity = await WebinarRepository.UpdateAsync(entity.Id, entity);
|
|
}
|
|
|
|
//
|
|
// Check if Enabled Change Update it ...
|
|
if (entity.Enabled != item.Enabled)
|
|
{
|
|
//
|
|
entity.Enabled = item.Enabled;
|
|
entity = await WebinarRepository.UpdateAsync(entity.Id, entity);
|
|
}
|
|
|
|
//
|
|
// Retrieve Entity Dto ...
|
|
var entityDto = await ToXWebinarDto(entity);
|
|
|
|
//
|
|
// Exclude Must Remove items ...
|
|
var mustRemoveTitleLocals = entityDto.Title.Locales.Where(e =>
|
|
!item.Title.Locales.Any(l =>
|
|
l.Language.ToNormalString() == e.Language.ToNormalString())
|
|
);
|
|
var mustRemoveDescriptionLocals = entityDto.Description.Locales.Where(e =>
|
|
!item.Description.Locales.Any(l =>
|
|
l.Language.ToNormalString() == e.Language.ToNormalString())
|
|
);
|
|
|
|
//
|
|
// Remove Specified Locales ...
|
|
|
|
//
|
|
// Titles ...
|
|
foreach (var locale in mustRemoveTitleLocals)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await TitleResourceProvider.Remove(
|
|
resource: entity.Title,
|
|
language: locale.Language
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
// Descriptions ...
|
|
foreach (var locale in mustRemoveDescriptionLocals)
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
await DescriptionResourceProvider.Remove(
|
|
resource: entity.Description,
|
|
language: locale.Language
|
|
);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
//
|
|
// Add Or Update Locales ...
|
|
|
|
//
|
|
// Title ...
|
|
var titleAddedLocales = await TitleResourceProvider.AddOrUpdate(
|
|
resource: entity.Title,
|
|
locales: item.Title.Locales
|
|
);
|
|
|
|
//
|
|
// Description ...
|
|
var descriptionAddedLocales = await DescriptionResourceProvider.AddOrUpdate(
|
|
resource: entity.Description,
|
|
locales: item.Description.Locales
|
|
);
|
|
|
|
//
|
|
entity = await WebinarRepository.GetAsync(entity.Id);
|
|
var result = await ToXWebinarDto(entity);
|
|
|
|
//
|
|
if (!result.IsNullOrDefault())
|
|
{
|
|
//
|
|
await SendPush(
|
|
action: XBaseEntityHubAction.Update.GetStringValue(),
|
|
payLoad: entity.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Webinar ...
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public async Task<XWebinarDto> GetWebinar(Guid id)
|
|
{
|
|
//
|
|
var entity = await WebinarRepository.GetAsync(id);
|
|
if (entity.IsNullOrDefault())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await ToXWebinarDto(entity);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Webinars ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XWebinarDto>> GetWebinars()
|
|
{
|
|
//
|
|
var list = await WebinarRepository.GetAllAsync();
|
|
var result = await list.SelectAsync(async l => await ToXWebinarDto(l));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve all Exists Webinar Ids ...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public IEnumerable<Guid> GetWebinarIds()
|
|
{
|
|
//
|
|
var result = WebinarRepository.AsQueryable().Select(l => l.Id);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Webinars ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XWebinarDto>> QueryWebinars(XQuery query)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataSercviceConfiguration);
|
|
|
|
//
|
|
// Since in Resourceable Entities we have to Search on Locales
|
|
// we Must Implement Senario Custom ...
|
|
var totalEntities = await WebinarRepository.GetAllAsync();
|
|
var itemsTasks = totalEntities.ToList().Select(e => ToXWebinarDto(e));
|
|
var items = (await Task.WhenAll(itemsTasks)).AsEnumerable();
|
|
// var items = await totalEntities.SelectAsync(async e => await ToXWebinarDto(e));
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<XWebinarDto>
|
|
{
|
|
Page = query.Page,
|
|
Items = items.ToList(),
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Webinar Ids ...
|
|
/// </summary>
|
|
/// <param name="query"></param>
|
|
/// <returns></returns>
|
|
public XQueryResult<Guid> QueryWebinarIds(XQuery query)
|
|
{
|
|
//
|
|
// Validate ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataSercviceConfiguration);
|
|
|
|
//
|
|
// Since in Resourceable Entities we have to Search on Locales
|
|
// we Must Implement Senario Custom ...
|
|
var items = GetWebinarIds();
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.Where(i => i.ToString().ToNormalString().Contains(query.Filter));
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Paging ...
|
|
items = items.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<Guid>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Specified Webinar ...
|
|
/// </summary>
|
|
/// <param name="webinarId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RemoveWebinar(
|
|
Guid webinarId,
|
|
string connectionId = null
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!webinarId.IsNull() &&
|
|
!webinarId.IsDefaultGuid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Get Entity ...
|
|
var entity = await WebinarRepository.GetAsync(webinarId);
|
|
result = !entity.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Handle Remove ...
|
|
var subscribers = await GetSubscribers(
|
|
webinarId: webinarId
|
|
);
|
|
try
|
|
{
|
|
//
|
|
await subscribers.SelectAsync(async s => await Unsubscribe(
|
|
webinarId: webinarId,
|
|
subscriberId: s.SubscriberId
|
|
));
|
|
|
|
//
|
|
string resourceID = webinarId.ToString();
|
|
await TitleResourceProvider.Remove(resourceID);
|
|
await DescriptionResourceProvider.Remove(resourceID);
|
|
|
|
//
|
|
await WebinarRepository.RemoveAsync(webinarId);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
// Check Entity Removed ...
|
|
result = !await WebinarRepository.IsExistsAsync(webinarId);
|
|
if (result)
|
|
{
|
|
//
|
|
await SendPush(
|
|
action: XBaseEntityHubAction.Delete.GetStringValue(),
|
|
payLoad: entity.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region WebinarSubscriber ...
|
|
/// <summary>
|
|
/// Subscribe a User to Webinar ...
|
|
/// </summary>
|
|
/// <param name="webinarId"></param>
|
|
/// <param name="subscriberId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> Subscribe(
|
|
Guid webinarId,
|
|
string subscriberId,
|
|
string connectionId = null
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!webinarId.IsNull() &&
|
|
!webinarId.IsDefaultGuid() &&
|
|
!subscriberId.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Webinar Exists ...
|
|
result = await WebinarRepository.IsExistsAsync(webinarId);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Webinar Entity ...
|
|
var webinar = await WebinarRepository.GetAsync(webinarId);
|
|
|
|
//
|
|
// Check Webinar Enabled ...
|
|
result = webinar.Enabled;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check User Exists ...
|
|
var device = IdentityProvider.GetDevice();
|
|
XOpenActionUserInfoDto userInfo = null;
|
|
try
|
|
{
|
|
//
|
|
userInfo = await IdentityProvider.GetUserInfo(
|
|
device: device,
|
|
userSelectByParam: subscriberId
|
|
);
|
|
}
|
|
catch { }
|
|
result = !userInfo.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Create Subscription Model ...
|
|
var entity = new XWebinarSubscriber
|
|
{
|
|
WebinarId = webinarId,
|
|
SubscriberId = subscriberId,
|
|
SubscribedOn = DateTime.UtcNow,
|
|
};
|
|
entity = await WebinarSubscriberRepository.AddAsync(entity);
|
|
result = !entity.IsNullOrDefault();
|
|
if (result)
|
|
{
|
|
//
|
|
await SendPush(
|
|
action: XWebinarEntityHubAction.Subscribe.GetStringValue(),
|
|
payLoad: entity.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Specified User Subscribed on a Webinar or not ...
|
|
/// </summary>
|
|
/// <param name="webinarId"></param>
|
|
/// <param name="subscriberId"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> IsSubscribed(
|
|
Guid webinarId,
|
|
string subscriberId
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!webinarId.IsNull() &&
|
|
!webinarId.IsDefaultGuid() &&
|
|
!subscriberId.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Webinar Exists ...
|
|
result = await WebinarRepository.IsExistsAsync(webinarId);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check User Exists ...
|
|
var device = IdentityProvider.GetDevice();
|
|
XOpenActionUserInfoDto userInfo = null;
|
|
try
|
|
{
|
|
//
|
|
userInfo = await IdentityProvider.GetUserInfo(
|
|
device: device,
|
|
userSelectByParam: subscriberId
|
|
);
|
|
}
|
|
catch { }
|
|
result = !userInfo.IsNullOrDefault();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = !(await WebinarSubscriberRepository.FindOneAsync(ws =>
|
|
ws.WebinarId == webinarId &&
|
|
ws.SubscriberId == subscriberId
|
|
)).IsNull();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unsubscribe Specified User from a Specified Webinar ...
|
|
/// </summary>
|
|
/// <param name="webinarId"></param>
|
|
/// <param name="subscriberId"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> Unsubscribe(
|
|
Guid webinarId,
|
|
string subscriberId,
|
|
string connectionId = null
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
|
|
//
|
|
// Validate ...
|
|
result =
|
|
!webinarId.IsNull() &&
|
|
!webinarId.IsDefaultGuid() &&
|
|
!subscriberId.IsNullOrEmpty();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Subscription ..
|
|
result = await IsSubscribed(
|
|
webinarId: webinarId,
|
|
subscriberId: subscriberId
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Webinar ...
|
|
var webinar = await WebinarRepository.GetAsync(webinarId);
|
|
|
|
//
|
|
// Retrieve Subscription Entity ...
|
|
var entity = await WebinarSubscriberRepository.FindOneAsync(ws =>
|
|
ws.WebinarId == webinarId &&
|
|
ws.SubscriberId == subscriberId
|
|
);
|
|
entity = await WebinarSubscriberRepository.RemoveAsync(entity);
|
|
result = !entity.IsNullOrDefault();
|
|
if (result)
|
|
{
|
|
//
|
|
await SendPush(
|
|
action: XWebinarEntityHubAction.Unsubscribe.GetStringValue(),
|
|
payLoad: entity.ToJSON(camelCase: true),
|
|
connectionId: connectionId
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specified Subscriber ...
|
|
/// </summary>
|
|
/// <param name="webinarId"></param>
|
|
/// <param name="subscriberId"></param>
|
|
/// <returns></returns>
|
|
public async Task<XWebinarSubscriberDto> GetSubscriber(
|
|
Guid webinarId,
|
|
string subscriberId
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!webinarId.IsNull() &&
|
|
!webinarId.IsDefaultGuid() &&
|
|
!subscriberId.IsNullOrEmpty();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Webinar and Validate it ...
|
|
var webinar = await WebinarRepository.GetAsync(webinarId);
|
|
isValid = !webinar.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Entity and Validate it ...
|
|
var entity = await WebinarSubscriberRepository.FindOneAsync(e =>
|
|
e.WebinarId == webinarId &&
|
|
e.SubscriberId == subscriberId
|
|
);
|
|
isValid = !entity.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Converts to Subscriber Dto ...
|
|
var result = await ToXWebinarSubscriberDto(entity);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all Specified Webinars Subscribers ...
|
|
/// </summary>
|
|
/// <param name="webinarId"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XWebinarSubscriberDto>> GetSubscribers(
|
|
Guid webinarId
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!webinarId.IsNull() &&
|
|
!webinarId.IsDefaultGuid();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve and Validate Webinar Entity ...
|
|
var webinar = await WebinarRepository.GetAsync(webinarId);
|
|
isValid = !webinar.IsNullOrDefault();
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var subscribers = await WebinarSubscriberRepository.FindManyAsync(e =>
|
|
e.WebinarId == webinarId
|
|
);
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = await subscribers
|
|
.SelectAsync(async s => await ToXWebinarSubscriberDto(s));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Specified Webinar's Subscribers ...
|
|
/// </summary>
|
|
/// <param name="webinarId"></param>
|
|
/// <param name="query"></param>
|
|
/// <returns></returns>
|
|
public async Task<XQueryResult<XWebinarSubscriberDto>> QuerySubscribers(
|
|
Guid webinarId,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Validate ...
|
|
bool isValid =
|
|
!query.IsNull() &&
|
|
!webinarId.IsNull() &&
|
|
!webinarId.IsDefaultGuid();
|
|
if (!isValid)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataSercviceConfiguration);
|
|
|
|
//
|
|
// Check Webinar Exists ...
|
|
isValid = await WebinarRepository.IsExistsAsync(webinarId);
|
|
if (!isValid)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve all Items ...
|
|
var items = await GetSubscribers(
|
|
webinarId: webinarId
|
|
);
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Try Filter Items ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
var filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Counting Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Sorting and Paging ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
var result = new XQueryResult<XWebinarSubscriberDto>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Hub Actions ...
|
|
/// <summary>
|
|
/// Send Custom Push Message ...
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <param name="payLoad"></param>
|
|
/// <param name="connectionId"></param>
|
|
/// <returns></returns>
|
|
public async Task SendPush(
|
|
string action,
|
|
string payLoad,
|
|
string connectionId = null
|
|
)
|
|
{
|
|
//
|
|
var actions = new List<string>
|
|
{
|
|
XBaseEntityHubAction.Add.GetStringValue(),
|
|
XBaseEntityHubAction.Update.GetStringValue(),
|
|
XBaseEntityHubAction.Delete.GetStringValue(),
|
|
XBaseEntityHubAction.AddMany.GetStringValue(),
|
|
XBaseEntityHubAction.DeleteMany.GetStringValue(),
|
|
XBaseEntityHubAction.UpdateMany.GetStringValue(),
|
|
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
|
|
XWebinarEntityHubAction.Subscribe.GetStringValue(),
|
|
XWebinarEntityHubAction.Unsubscribe.GetStringValue(),
|
|
};
|
|
|
|
//
|
|
// Validate ...
|
|
var isValid =
|
|
!Hub.IsNull() &&
|
|
!action.IsNullOrEmpty() &&
|
|
actions.Contains(action);
|
|
if (!isValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var clients = Hub.Clients.All;
|
|
if (!connectionId.IsNullOrEmpty())
|
|
{
|
|
clients = Hub.Clients.AllExcept(connectionId);
|
|
}
|
|
await clients.SendAsync(action, payLoad, connectionId);
|
|
}
|
|
#endregion
|
|
}
|
|
} |