using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR; using xCommons.Extensions; using xDataService.Configuration; using xDataService.Extensions; using xExceptions.Constants; using xIdentityModels.Dtos; using xIdentityModels.Models; 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; using XFileDto = xFileService.Models.Dtos.XFileDto; namespace xWebinarService.Providers { /// /// Implement all Webinar Related Things here ... /// public class XWebinarProvider : IXWebinarProvider { // #region Props ... public IHubContext Hub { get; } public IXIdentityProvider IdentityProvider { get; } public IXWebinarRepository WebinarRepository { get; } public IXWebinarTagProvider WebinarTagProvider { get; } public IXWebinarFileProvider WebinarFileProvider { 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, IXWebinarTagProvider webinarTagProvider, IXWebinarFileProvider webinarFileProvider, XDataServiceConfiguration dataSercviceConfiguration, IXWebinarTitleResourceProvider titleResourceProvider, IXWebinarSubscriberRepository webinarSubscriberRepository, IXWebinarDescriptionResourceProvider descriptionResourceProvider, IHubContext hub = null ) { // Hub = hub; IdentityProvider = identityProvider; WebinarRepository = webinarRepository; WebinarTagProvider = webinarTagProvider; WebinarFileProvider = webinarFileProvider; TitleResourceProvider = titleResourceProvider; DataSercviceConfiguration = dataSercviceConfiguration; WebinarSubscriberRepository = webinarSubscriberRepository; DescriptionResourceProvider = descriptionResourceProvider; } #endregion // #region Tools ... /// /// Converts Specified XWebinar Entity to it's Corresponding Dto Presentation /// and also Fill Owner and Title/Description Resources ... /// /// /// public async Task 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; } /// /// Converts Specified WebinarSubscriber Entity to it's Dto Presentation ... /// /// /// public async Task 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 ... /// /// Create Webinar ... /// /// /// /// /// /// /// public async Task CreateWebinar( XWebinarDto item, IEnumerable tags = null, IFormFileCollection files = null, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // // Validate ... bool isValid = !item.IsNull() && !item.Title.IsNull() && !item.Description.IsNull() && !userInfo.IsNullOrDefault() && !item.OwnerId.IsNullOrEmpty() && userInfo.UserId == item.OwnerId; 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(); } // // Check For Files ... isValid = !files.IsNull(); if (isValid) { // try { // await UploadFiles( id: entity.Id, files: files, userInfo: userInfo ); } catch { } } // // Check For Tags ... isValid = !tags.IsNull() && tags.HasChild(); if (isValid) { // try { // await TagsAttach( tags: tags, id: entity.Id, userInfo: userInfo, connectionId: connectionId, true // ); } catch { } } // await SendPush( action: XBaseEntityHubAction.Add.GetStringValue(), payLoad: entity.ToJSON(camelCase: true), connectionId: connectionId ); // // Convert Entity to Dto ... var result = await ToXWebinarDto(entity); return result; } /// /// Update a Webinar ... /// /// /// /// /// public async Task UpdateWebinar( XWebinarDto item, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // // Since Medias and Tags Manages Separatly, here // we dont need to ensure that ... // // Validate ... bool isValid = !item.Id.IsNull() && !item.IsNullOrDefault() && !item.Id.IsDefaultGuid() && !userInfo.IsNullOrDefault() && !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 Permissions ... isValid = await HasPermission(item.Id, userInfo); if (!isValid) { XException.NotAllowed.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; } /// /// Retrieve Specified Webinar ... /// /// /// public async Task GetWebinar(Guid id) { // var entity = await WebinarRepository.GetAsync(id); if (entity.IsNullOrDefault()) { XException.NotFound.Throw(); } // var result = await ToXWebinarDto(entity); return result; } /// /// Retrieve all Exists Webinars ... /// /// public async Task> GetWebinars() { // var list = await WebinarRepository.GetAllAsync(); var result = await list.SelectAsync(async l => await ToXWebinarDto(l)); // return result; } /// /// Retrieve all Exists Webinar Ids ... /// /// public IEnumerable GetWebinarIds() { // var result = WebinarRepository.AsQueryable().Select(l => l.Id); // return result; } /// /// Query Webinars ... /// /// /// public async Task> 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 list = new List(); foreach (var entity in totalEntities) { // var dto = await ToXWebinarDto(entity); list.Add(dto); } var items = list.AsEnumerable(); 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 .ToList() .ApplySorting( query.SortBy, query.IsAscending ); // // Apply Paging ... items = items .ToList() .ApplyPaging( query.Page, query.PageSize ); } // // Prepare Result ... var result = new XQueryResult { Page = query.Page, Items = items.ToList(), PageSize = query.PageSize, TotalPages = totalPagesCount, TotalItems = totalItemsCount, TotalFilteredPages = filteredPagesCount, TotalFilteredItems = filteredItemsCount }; // return result; } /// /// Conditional Query Webinars ... /// /// /// /// public async Task> ConditionalQueryWebinars( Expression> whereClause, XQuery query ) { // // Validate ... if (query.IsNull() || whereClause.IsNull()) { XException.InvalidArgs.Throw(); } // // Normalize ... query = query.NormalizeQuery(DataSercviceConfiguration); // // Compile Expression ... var whereFunc = whereClause.Compile(); // // Since in Resourceable Entities we have to Search on Locales // we Must Implement Senario Custom ... var totalEntities = await WebinarRepository.GetAllAsync(); // var list = new List(); foreach (var entity in totalEntities) { // var dto = await ToXWebinarDto(entity); // // Validate and Check Conditions ... if (!dto.IsNullOrDefault() && whereFunc(dto)) { list.Add(dto); } } var items = list.AsEnumerable(); 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 .ToList() .ApplySorting( query.SortBy, query.IsAscending ); // // Apply Paging ... items = items .ToList() .ApplyPaging( query.Page, query.PageSize ); } // // Prepare Result ... var result = new XQueryResult { Page = query.Page, Items = items.ToList(), PageSize = query.PageSize, TotalPages = totalPagesCount, TotalItems = totalItemsCount, TotalFilteredPages = filteredPagesCount, TotalFilteredItems = filteredItemsCount }; // return result; } /// /// Query Owned Webinars ... /// /// /// public async Task> QueryOwnedWebinars( XQuery query, XUserClaimsInfoDto userInfo = null ) { // // Validate ... var isValid = !query.IsNullOrDefault() && !userInfo.IsNullOrDefault(); if (!isValid) { XException.InvalidArgs.Throw(); } // Expression> whereClause = d => d.OwnerId == userInfo.UserId; var result = await ConditionalQueryWebinars( query: query, whereClause: whereClause ); return result; } /// /// Query Joinable Webinars ... /// /// /// public async Task> QueryJoinableWebinars( XQuery query, XUserClaimsInfoDto userInfo = null ) { // // Validate ... var isValid = !query.IsNullOrDefault() && !userInfo.IsNullOrDefault(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Create an Expression to Check Specified Webinar is Joinable by Provided User Info or not ... Expression> whereClause = d => d.OwnerId == userInfo.UserId || d.Type == XWebinarType.Public || WebinarSubscriberRepository.AsQueryable().Any(ws => ws.WebinarId == d.Id && ws.SubscriberId == userInfo.UserId); var result = await ConditionalQueryWebinars( query: query, whereClause: whereClause ); return result; } /// /// Query Webinar Ids ... /// /// /// public XQueryResult 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 { Items = items, Page = query.Page, PageSize = query.PageSize, TotalPages = totalPagesCount, TotalItems = totalItemsCount, TotalFilteredPages = filteredPagesCount, TotalFilteredItems = filteredItemsCount }; // return result; } /// /// Remove Specified Webinar ... /// /// /// /// /// public async Task RemoveWebinar( Guid webinarId, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // bool result = false; // // Validate ... result = !webinarId.IsNull() && !webinarId.IsDefaultGuid(); if (!result) { return result; } // // Check Permissions ... result = await HasPermission(webinarId, userInfo); if (!result) { XException.NotAllowed.Throw(); } // // 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 { } // // Detach Tags ... try { await TagsDetach(entity.Id, userInfo); } catch { } // // Remove Files ... try { // var medias = await WebinarFileProvider.GetAllFor(entity.Id); if (!medias.IsNull() && medias.HasChild()) { await RemoveFiles(entity.Id, string.Empty, userInfo); } } 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 ... /// /// Subscribe a User to Webinar ... /// /// /// /// /// public async Task 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; } /// /// Check Specified User Subscribed on a Webinar or not ... /// /// /// /// public async Task 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; } /// /// Unsubscribe Specified User from a Specified Webinar ... /// /// /// /// /// public async Task 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; } /// /// Retrieve Specified Subscriber ... /// /// /// /// public async Task 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; } /// /// Get all Specified Webinars Subscribers ... /// /// /// public async Task> 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; } /// /// Query Specified Webinar's Subscribers ... /// /// /// /// public async Task> 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 { Items = items, Page = query.Page, PageSize = query.PageSize, TotalPages = totalPagesCount, TotalItems = totalItemsCount, TotalFilteredPages = filteredPagesCount, TotalFilteredItems = filteredItemsCount }; // return result; } #endregion // #region File Actions ... /// /// Upload Files ... /// /// /// /// /// /// public async Task> UploadFiles( Guid id, IFormFileCollection files, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // // Validate ... var isValid = !id.IsNull() && !id.IsDefaultGuid() && !userInfo.IsNullOrDefault(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Check Permission ... isValid = await HasPermission(id, userInfo); if (!isValid) { XException.NotAllowed.Throw(); } // var result = new List(); try { // result = (await WebinarFileProvider.Upload( files: files, forProvidedId: id, userInfo: userInfo, connectionId: connectionId )) .ToList(); } catch { } // return result; } /// /// Remove Specified Files ... /// /// /// /// /// /// public async Task> RemoveFiles( Guid id, string ids = null, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // // Validate ... var isValid = !id.IsNull() && !id.IsDefaultGuid() && !userInfo.IsNullOrDefault(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Check Permission ... isValid = await HasPermission(id, userInfo); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await WebinarFileProvider.Remove( forProvidedId: id, ids: ids, userInfo: userInfo, connectionId: connectionId ); return result; } /// /// Get Webinar Files ... /// /// /// public async Task> GetFiles(Guid id) { // var result = new List(); // var dto = await GetWebinar(id); if (!dto.IsNullOrDefault()) { // result = (await WebinarFileProvider .GetAllFor(id)) .ToList(); } // return result; } #endregion // #region Tags Actions ... /// /// Attach Tag to Specified File ... /// /// /// /// /// /// /// public async Task TagAttach( string tag, Guid id, XUserClaimsInfoDto userInfo = null, string connectionId = null, bool forceAttachToFiles = true ) { // // Validate ... var isValid = !tag.IsNullOrEmpty() && !id.IsNull() && !id.IsDefaultGuid() && !userInfo.IsNullOrDefault(); if (isValid) { // // Check Permissions ... isValid = await HasPermission( id: id, userInfo: userInfo ); if (!isValid) { XException.NotAllowed.Throw(); } // try { // // Attached Tag to Webinar ... await WebinarTagProvider.Attach(tag, id, connectionId); // if (forceAttachToFiles) { // var medias = await WebinarFileProvider.GetAllFor(id); isValid = !medias.IsNull() && medias.HasChild(); if (isValid) { // foreach (var media in medias) { // await WebinarFileProvider.Provider.TagAttach( tag, media.Id, userInfo, connectionId ); } } } } catch { } } } /// /// Detach Tag fro Specified File ... /// /// /// /// /// /// /// public async Task TagDetach( string tag, Guid id, XUserClaimsInfoDto userInfo = null, string connectionId = null, bool forceDetachFromFiles = true ) { // // Validate ... var isValid = !tag.IsNullOrEmpty() && !id.IsNull() && !id.IsDefaultGuid(); if (isValid) { // // Check Permissions ... isValid = await HasPermission( id: id, userInfo: userInfo ); if (!isValid) { XException.NotAllowed.Throw(); } // try { // await WebinarTagProvider.Detach(tag, id, connectionId); // if (forceDetachFromFiles) { // var medias = await WebinarFileProvider.GetAllFor(id); isValid = !medias.IsNull() && medias.HasChild(); if (isValid) { // foreach (var media in medias) { // await WebinarFileProvider.Provider.TagDetach( tag, media.Id, userInfo, connectionId ); } } } } catch { } } } /// /// Attach Tags for Specified File ... /// /// /// /// /// /// /// public async Task TagsAttach( IEnumerable tags, Guid id, XUserClaimsInfoDto userInfo = null, string connectionId = null, bool forceAttachToFiles = true ) { // // Validate ... var isValid = !tags.IsNull() && tags.HasChild() && !id.IsNull() && !id.IsDefaultGuid(); if (isValid) { // // Check Permissions ... isValid = await HasPermission( id: id, userInfo: userInfo ); if (!isValid) { XException.NotAllowed.Throw(); } // try { // foreach (var tag in tags) { // await TagAttach( tag, id, userInfo, connectionId, forceAttachToFiles ); } } catch { } } } /// /// Detach Tags for Specified File ... /// /// /// /// /// /// /// public async Task TagsDetach( IEnumerable tags, Guid id, XUserClaimsInfoDto userInfo = null, string connectionId = null, bool forceDetachFromFiles = true ) { // // Validate ... var isValid = !tags.IsNull() && tags.HasChild() && !id.IsNull() && !id.IsDefaultGuid(); if (isValid) { // // Check Permissions ... isValid = await HasPermission( id: id, userInfo: userInfo ); if (!isValid) { XException.NotAllowed.Throw(); } // try { // foreach (var tag in tags) { // await TagDetach( tag, id, userInfo, connectionId, forceDetachFromFiles ); } } catch { } } } /// /// Detach all Attached Tags for Specified File ... /// /// /// /// /// public async Task TagsDetach( Guid id, XUserClaimsInfoDto userInfo = null, string connectionId = null, bool forceDetachFromFiles = true ) { // // Validate ... var isValid = !id.IsNull() && !id.IsDefaultGuid(); if (isValid) { // // Check Permissions ... isValid = await HasPermission( id: id, userInfo: userInfo ); if (!isValid) { XException.NotAllowed.Throw(); } // try { // var tags = await WebinarTagProvider.RemoveTagsFor(id, connectionId); // if (forceDetachFromFiles) { // var medias = await WebinarFileProvider.GetAllFor(id); if (!medias.IsNull() && medias.HasChild()) { // foreach (var media in medias) { // await WebinarFileProvider.Provider.TagsDetach(media.Id, userInfo, connectionId); } } } } catch { } } } #endregion // #region Hub Actions ... /// /// Send Custom Push Message ... /// /// /// /// /// public async Task SendPush( string action, string payLoad, string connectionId = null ) { // var actions = new List { 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); } try { await clients.SendAsync(action, payLoad, connectionId); } catch { } } #endregion // #region Private ... /// /// Check Specified User Info Has Permissions for Specified Webinar ... /// /// /// /// private async Task HasPermission( Guid id, XUserClaimsInfoDto userInfo = null ) { // var result = false; // // Validate ... result = !id.IsNull() && !id.IsDefaultGuid() && !userInfo.IsNullOrDefault(); if (!result) { XException.InvalidArgs.Throw(); } // // Check Item Exists ... var dto = await GetWebinar(id); result = !dto.IsNullOrDefault(); if (!result) { XException.NotFound.Throw(); } // result = dto.OwnerId == userInfo.UserId || userInfo.Roles.Any(r => r.ToNormalString() == "admin"); // return result; } #endregion } }