private CommunityEvent CreateGenericEvent(Int32 idCommunity, CommunityEventItem item, CommunityEventType eventType, litePerson person) { CommunityEvent oEventItem = new CommunityEvent(); oEventItem.IdCommunityOwner = idCommunity; oEventItem.ForEver = false; oEventItem.IsMacro = false; oEventItem.IsRepeat = false; oEventItem.IsVisible = item.IsVisible; oEventItem.Items = new List <CommunityEventItem>(); oEventItem.Link = item.Link; if (item.ModifiedOn.Equals(DateTime.MinValue)) { oEventItem.ModifiedOn = DateTime.Now; item.ModifiedOn = oEventItem.ModifiedOn; } else { oEventItem.ModifiedOn = item.ModifiedOn; } oEventItem.Name = ""; ////DiaryItem.Title oEventItem.Note = item.Note; oEventItem.NotePlain = item.NotePlain; oEventItem.Owner = person; oEventItem.Place = item.Place; oEventItem.Year = item.StartDate.Year; oEventItem.EventType = eventType; if (item.StartDate.Month < 9) { oEventItem.Year = oEventItem.Year - 1; } return(oEventItem); }
private EmbedBuilder CreateEventProposalEmbed(CommunityEvent Event) { IUser Author = DiscordSocketClient.GetUser(Event.ProposerID); DateTimeOffset Release = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone)); return(CreateEventProposalEmbed(Event.ID, Event.Status, Author, Release, Event.Description, Event.ResolveReason)); }
/// <summary> /// A callback method to be called when an event suggestion is declined. It sets the status to denied and handles timer cleanup. /// </summary> /// <param name="EventID">The unique numerical ID for the target event.</param> /// <param name="Reason">The optional reason why the event was declined.</param> /// <returns>A <c>Task</c> object, which can be awaited until this method completes successfully.</returns> public async Task DeclineEventCallback(int EventID, string Reason = "") { CommunityEvent Event = GetEvent(EventID); IUser Proposer = DiscordSocketClient.GetUser(Event.ProposerID); if (Event == null) { return; } Event.ResolveReason = Reason; await UpdateEventProposal(Event.ID); if (TimerService.TimerExists(Event.ReleaseTimer)) { TimerService.RemoveTimer(Event.ReleaseTimer); } await BuildEmbed(EmojiEnum.Annoyed) .WithTitle("Event has been declined!") .WithDescription($"Event #{Event.ID} has been declined.") .WithCurrentTimestamp() .SendDMAttachedEmbed(Context.Channel, BotConfiguration, Proposer, BuildEmbed(EmojiEnum.Love) .WithTitle("Your Event has been Declined!") .WithDescription(Event.Description) .AddField(Reason.Length > 0, "Reason: ", Reason)); Event.Status = EventStatus.Denied; CommunityEventsDB.SaveChanges(); }
/// <summary> /// Manually removes an event, automatically denying it and preventing it from running. It also deleted the associated proposal. /// </summary> /// <param name="EventID">The unique ID of the target Event.</param> /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns> public async Task RemoveEvent(int EventID) { CommunityEvent Event = GetEvent(EventID); if (Event.Status == EventStatus.Released) { await BuildEmbed(EmojiEnum.Annoyed) .WithTitle("Event already released!") .WithDescription("You can't remove an event that has already been released!") .WithCurrentTimestamp() .SendEmbed(Context.Channel); } if (TimerService.TimerExists(Event.ReleaseTimer)) { TimerService.RemoveTimer(Event.ReleaseTimer); } Event.Status = EventStatus.Removed; await UpdateEventProposal(Event.ID); CommunityEventsDB.SaveChanges(); await BuildEmbed(EmojiEnum.Love) .WithTitle("Event was successfully removed!") .WithDescription($"The event \"{Event.Description}\" has been removed from the proposal system.") .WithCurrentTimestamp() .SendEmbed(Context.Channel); }
public void SaveItem(Int32 idCommunity, long idItem, CommunityEventItem dto, DateTime startDate, DateTime endDate, List <dtoWeekDay> weekDays, String description, String descriptionPlain) { if (UserContext.isAnonymous) { View.DisplaySessionTimeout(idCommunity, idItem); } else { CommunityEventType type = Service.GetDiaryEventType(); CommunityEvent eventObj = Service.AddMultipleItems(idCommunity, dto, description, descriptionPlain, UserContext.CurrentUserID, type, startDate, endDate, weekDays); if (eventObj == null) { View.SetBackToDiary(idCommunity, 0); } else if (eventObj.Items != null && eventObj.Items.Count > 0) { View.SendToItemsList(idCommunity, eventObj.Items.FirstOrDefault().Id); } else { View.SetBackToDiary(idCommunity, 0); } } }
public CommunityEvent AddMultipleItems(Int32 idCommunity, CommunityEventItem dtoItem, String description, String descriptionPlain, int ownerId, CommunityEventType eventType, DateTime startDate, DateTime endDate, List <dtoWeekDay> weekDays) { CommunityEvent communityEvent = null; try { litePerson person = Manager.GetLitePerson(ownerId); liteCommunity community = Manager.GetLiteCommunity(idCommunity); if ((community != null && idCommunity > 0) && person != null) { List <dtoWeekDayRecurrence> itemsToInsert = dtoWeekDayRecurrence.CreateRecurrency(startDate, endDate, weekDays); if (itemsToInsert.Count > 0) { Manager.BeginTransaction(); communityEvent = CreateGenericEvent(idCommunity, dtoItem, eventType, person); Manager.SaveOrUpdate(communityEvent); foreach (dtoWeekDayRecurrence recurrence in itemsToInsert) { CommunityEventItem eventItem = new CommunityEventItem() { IdCommunityOwner = idCommunity, EventOwner = communityEvent, Owner = person, CreatedBy = person, CreatedOn = DateTime.Now }; eventItem.ModifiedBy = eventItem.CreatedBy; eventItem.ModifiedOn = eventItem.CreatedOn; eventItem.Note = dtoItem.Note; eventItem.NotePlain = dtoItem.NotePlain; eventItem.Place = dtoItem.Place; eventItem.Title = dtoItem.Title; eventItem.StartDate = recurrence.StartDate; eventItem.EndDate = recurrence.EndDate; eventItem.ShowDateInfo = dtoItem.ShowDateInfo; eventItem.IsVisible = dtoItem.IsVisible; eventItem.Link = dtoItem.Link; eventItem.AllowEdit = true; Manager.SaveOrUpdate(eventItem); if (!String.IsNullOrEmpty(description)) { DescriptionEventItem descriptionItem = new DescriptionEventItem() { Id = eventItem.Id, Description = description }; descriptionItem.DescriptionPlain = descriptionPlain; Manager.SaveOrUpdate(descriptionItem); } communityEvent.Items.Add(eventItem); } Manager.SaveOrUpdate(communityEvent); Manager.Commit(); } } } catch (Exception ex) { Manager.RollBack(); communityEvent = null; } return(communityEvent); }
/// <summary> /// Updates a proposal linked to a given ID, by setting its status and relevant information, modifying the linked embed. /// </summary> /// <param name="EventID">The ID of the target event to update.</param> /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns> public async Task UpdateEventProposal(int EventID) { CommunityEvent Event = GetEvent(EventID); if (Event == null) { return; } if (Event.EventType == EventType.Official) { return; } SocketChannel ProposalChannel = DiscordSocketClient.GetChannel(CommunityConfiguration.EventsNotificationsChannel); IUserMessage Proposal = null; if (ProposalChannel is SocketTextChannel TextChannel) { try { Proposal = await TextChannel.GetMessageAsync(Event.EventProposal) as IUserMessage; } catch (HttpException) { await BuildEmbed(EmojiEnum.Annoyed) .WithTitle("Failed to update event proposal") .WithDescription("The message doesn't exist anymore! Perhaps it was deleted?") .AddField("Message ID", Event.EventProposal) .SendEmbed(Context.Channel); } } if (Proposal == null) { return; } string ProposalText = Event.Status switch { EventStatus.Pending => $"**New Event Proposal >>>** {CommunityConfiguration.EventsNotificationMention}", EventStatus.Approved => $"**Upcoming Event [{DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone)):MMM M 'at' h:mm tt}] >>>**", EventStatus.Released => $"**Released Event**", _ => $"**{Event.Status} Event Proposal >>>**" }; if (Event.Status is EventStatus.Pending or EventStatus.Approved or EventStatus.Released) { string Link = Event.Description.GetHyperLinks().FirstOrDefault(); if (Link != null && Link.Length > 0) { ProposalText += $"\n{Link}"; } } await Proposal.ModifyAsync(Properties => { Properties.Content = ProposalText; Properties.Embed = CreateEventProposalEmbed(Event).Build(); }); }
/// <summary> /// Gets an event from the events database given its <paramref name="Description"/>. /// </summary> /// <param name="Description">The text Description of the target event.</param> /// <returns>An event with the exact given <paramref name="Description"/>.</returns> public CommunityEvent GetEvent(string Description) { CommunityEvent Event = CommunityEventsDB.Events .AsQueryable() .Where(Event => Event.Description == Description) .FirstOrDefault(); return(Event); }
/// <summary> /// A function to be called when an event is released or updated after its release date. /// </summary> /// <param name="EventID">The unique numeric ID of the target event.</param> /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns> public async Task ReleaseEvent(int EventID) { CommunityEvent Event = GetEvent(EventID); if (Event == null) { return; } if (Event.Status is EventStatus.Denied or EventStatus.Removed or EventStatus.Released) { return; } if (Event.Status == EventStatus.Expired && CommunityConfiguration.FailOnOverdueApproval) { return; } IUser User = DiscordSocketClient.GetUser(Event.ProposerID); if (Event.Status == EventStatus.Pending) { Event.Status = EventStatus.Expired; try { await BuildEmbed(EmojiEnum.Sign) .WithTitle("Event Expired") .WithDescription($"One of your events expired without the admins giving their feedback in time! \n{Event.Description}") .WithCurrentTimestamp() .SendEmbed(await User.GetOrCreateDMChannelAsync()); } catch (HttpException) { } } else { Event.Status = EventStatus.Released; ulong ChannelID = Event.EventType == EventType.Official ? CommunityConfiguration.OfficialEventsChannel : CommunityConfiguration.CommunityEventsChannel; IMessageChannel Channel = DiscordSocketClient.GetChannel(ChannelID) as IMessageChannel; string RoleMention = $"<@&{(Event.EventType == EventType.Official ? CommunityConfiguration.OfficialEventsNotifiedRole : CommunityConfiguration.CommunityEventsNotifiedRole)}>"; string ProposalText = $"**New {(Event.EventType == EventType.Official ? "Official" : "Community")} Event >>>** {RoleMention} \n" + $"*Event by <@{Event.ProposerID}>:* \n" + $"{Event.Description}"; await Channel.SendMessageAsync(text : ProposalText); } await UpdateEventProposal(Event.ID); CommunityEventsDB.SaveChanges(); }
/// <summary> /// Creates a standardized field to display an event in an embed. /// </summary> /// <param name="Event">The event to take the field parameters from.</param> /// <returns>An EmbedFieldBuilder which can be used as an argument for <c>EmbedBuilder.AddField(FieldEmbedBuilder)</c>.</returns> public EmbedFieldBuilder GenerateEventField(CommunityEvent Event) { DateTimeOffset Release = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone)); DateTimeOffset ProposeTime = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeProposed).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone)); string TimeInfo = Event.Status switch { EventStatus.Expired => $"**Proposed:** {ProposeTime:G} \n**Expired:** {Release:G}", EventStatus.Pending => $"**Proposed:** {ProposeTime:G} \n**Programmed for:** {Release:G}", EventStatus.Approved or EventStatus.Released => $"Release: {Release:G}", EventStatus.Removed or EventStatus.Denied or _ => $"**Proposed:** {ProposeTime:G}" }; return(new EmbedFieldBuilder() .WithName($"Event #{Event.ID} [**{Event.Status.ToString().ToUpper()}**]:") .WithValue($"{(Event.Description.Length > 256 ? Event.Description[..256] + "..." : Event.Description)}\n" +
/// <summary> /// Edits the target event to change its description to something new. It also deletes the old proposal and creates a new one with the updated information. /// </summary> /// <param name="EventID">The unique ID of the target event.</param> /// <param name="NewDescription">The new Description for the target event.</param> /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns> public async Task EditEvent(int EventID, string NewDescription) { CommunityEvent Event = GetEvent(EventID); if (NewDescription.Length > 1000) { await BuildEmbed(EmojiEnum.Annoyed) .WithTitle("Event description too long!") .WithDescription($"Try to keep the description under 1000 characters, the current description is {NewDescription.Length} characters long.") .SendEmbed(Context.Channel); return; } if (Event.EventType != EventType.Official) { if (Event.Status is EventStatus.Approved or EventStatus.Denied or EventStatus.Removed or EventStatus.Released) { await BuildEmbed(EmojiEnum.Annoyed) .WithTitle("Event is not pending!") .WithDescription($"This event has already been {Event.Status}; and thus can't be edited. \nYou can remove this event and propose a new one if you wish to change it.") .WithCurrentTimestamp() .SendEmbed(Context.Channel); return; } } Event.Description = NewDescription; await UpdateEventProposal(Event.ID); CommunityEventsDB.SaveChanges(); await BuildEmbed(EmojiEnum.Love) .WithTitle("Event was successfully edited!") .WithDescription($"Event #{Event.ID}'s description has been changed to: \n" + $"{Event.Description}") .WithCurrentTimestamp() .SendEmbed(Context.Channel); }
/// <summary> /// Resolves an event proposal by setting it as approved or declined depending on <paramref name="Action"/>. /// </summary> /// <param name="EventID">The unique numeric ID of the target event.</param> /// <param name="Reason">The optional reason behind the resolution.</param> /// <param name="Action">Either Action.Approve or Action.Decline, defines how the event proposal is resolved.</param> /// <returns>A <c>Task</c> object, which can be awaited until the method completes successfully.</returns> public async Task ResolveEventProposal(int EventID, string Reason, Enums.ActionType Action) { CommunityEvent Event = GetEvent(EventID); if (Event == null) { return; } if (Event.Status is EventStatus.Approved or EventStatus.Denied or EventStatus.Released or EventStatus.Removed) { await BuildEmbed(EmojiEnum.Annoyed) .WithTitle("Event already resolved!") .WithDescription($"Event #{EventID} has already been {Event.Status}.") .SendEmbed(Context.Channel); return; } Event.Status = Action switch { Enums.ActionType.Approve => EventStatus.Approved, Enums.ActionType.Decline => EventStatus.Denied, _ => Event.Status }; if (Action == Enums.ActionType.Approve) { await ApproveEventCallback(EventID, Reason); } else { await DeclineEventCallback(EventID, Reason); } Event.ResolveReason = Reason; await UpdateEventProposal(Event.ID); }
public Boolean PhisicalDeleteItem(CommunityEventItem item, String baseFilePath, String baseThumbnailPath) { Boolean result = (item == null); if (item != null) { Boolean isInTransaction = Manager.IsInTransaction(); try { CommunityEvent eventOwner = item.EventOwner; List <string> filesToRemove = new List <string>(); if (!isInTransaction) { Manager.BeginTransaction(); } List <EventItemFile> attachments = QueryAttachments(a => a.IdItemOwner == item.Id).ToList(); List <liteModuleLink> links = attachments.Where(a => a.Link != null).Select(a => a.Link).ToList(); foreach (EventItemFile attachment in attachments.Where(a => a.Item != null && a.Item.IsInternal)) { filesToRemove.Add(ServiceRepository.GetItemDiskFullPath(baseFilePath, attachment.Item)); filesToRemove.Add(ServiceRepository.GetItemThumbnailFullPath(baseThumbnailPath, attachment.Item)); Manager.DeletePhysical(attachment.Item); if (attachment.Version != null) { Manager.DeletePhysical(attachment.Version); } } if (links.Any()) { Manager.DeletePhysicalList(links); } if (attachments.Any()) { Manager.DeletePhysicalList(attachments); } if (eventOwner != null) { eventOwner.Items.Remove(item); } Manager.DeletePhysical(item); if (eventOwner.Items.Count > 0) { Manager.SaveOrUpdate(eventOwner); } else { Manager.DeletePhysical(eventOwner); } if (!isInTransaction) { Manager.Commit(); } Delete.Files(filesToRemove); } catch (Exception ex) { if (!isInTransaction) { Manager.RollBack(); } result = false; } } return(result); }
public CommunityEventItem SaveEventItem(int idCommunity, CommunityEventItem unsavedItem, String description, String descriptionPlain, int ownerId, int savedById, CommunityEventType eventType) { CommunityEventItem eventItem = null; litePerson owner = Manager.GetLitePerson(ownerId); litePerson savedBy = Manager.GetLitePerson(savedById); liteCommunity community = Manager.GetLiteCommunity(idCommunity); CommunityEvent eventOwner = unsavedItem.EventOwner; try { if (owner != null && savedBy != null && (community != null && idCommunity > 0)) { Manager.BeginTransaction(); if (unsavedItem.Id == 0) { eventItem = new CommunityEventItem(); eventItem.Owner = owner; eventItem.CreatedBy = savedBy; eventItem.CreatedOn = DateTime.Now; eventItem.ModifiedBy = savedBy; eventItem.ModifiedOn = eventItem.CreatedOn; eventItem.IdCommunityOwner = idCommunity; eventItem.AllowEdit = true; } else { eventItem = Manager.Get <CommunityEventItem>(unsavedItem.Id); if (eventItem.Owner == null) { eventItem.Owner = savedBy; } eventItem.ModifiedBy = savedBy; eventItem.ModifiedOn = DateTime.Now; } eventItem.Note = unsavedItem.Note; eventItem.NotePlain = unsavedItem.NotePlain; eventItem.Place = unsavedItem.Place; eventItem.Title = unsavedItem.Title; eventItem.StartDate = unsavedItem.StartDate; eventItem.EndDate = unsavedItem.EndDate; eventItem.ShowDateInfo = unsavedItem.ShowDateInfo; eventItem.IsVisible = unsavedItem.IsVisible; eventItem.Link = unsavedItem.Link; if (unsavedItem.Id == 0) { eventOwner = CreateGenericEvent(idCommunity, eventItem, eventType, savedBy); Manager.SaveOrUpdate(eventOwner); eventItem.EventOwner = eventOwner; if (eventOwner.Items == null) { eventOwner.Items = new List <CommunityEventItem>(); } eventOwner.Items.Add(eventItem); Manager.SaveOrUpdate(eventItem); Manager.SaveOrUpdate(eventOwner); } else { Manager.SaveOrUpdate(eventItem); } DescriptionEventItem descriptionItem = Manager.Get <DescriptionEventItem>(eventItem.Id); if (descriptionItem == null && !string.IsNullOrEmpty(description)) { descriptionItem = new DescriptionEventItem() { Id = eventItem.Id } } ; if (descriptionItem != null) { descriptionItem.Description = description; descriptionItem.DescriptionPlain = descriptionPlain; Manager.SaveOrUpdate(descriptionItem); } Manager.Commit(); } } catch (Exception ex) { Manager.RollBack(); eventItem = null; } return(eventItem); }
/// <summary> /// Gets an event from the events database given its <paramref name="EventID"/>. /// </summary> /// <param name="EventID">The ID of the target event.</param> /// <returns>An event whose ID is exactly that given by <paramref name="EventID"/>.</returns> public CommunityEvent GetEvent(int EventID) { CommunityEvent Event = CommunityEventsDB.Events.Find(EventID); return(Event); }
public void ViewEvent(CommunityEvent obj) { OnViewEvent(obj); }
/// <summary> /// A callback method to be called when an event suggestion is approved. It sets the status to approved and handles expired events. /// </summary> /// <param name="EventID">The unique numerical ID for the target event.</param> /// <param name="Reason">The optional reason for approval of the event.</param> /// <returns>A <c>Task</c> object, which can be awaited until this method completes successfully.</returns> public async Task ApproveEventCallback(int EventID, string Reason = "") { CommunityEvent Event = GetEvent(EventID); IUser Proposer = DiscordSocketClient.GetUser(Event.ProposerID); if (Event == null) { return; } if (Event.Status == EventStatus.Expired) { if (CommunityConfiguration.FailOnOverdueApproval) { await BuildEmbed(EmojiEnum.Annoyed) .WithTitle("This Event has already expired!") .WithDescription("Expired events can't be approved (FailOnOverdueApproval configuration is activated)") .WithCurrentTimestamp() .SendEmbed(Context.Channel); return; } else { await BuildEmbed(EmojiEnum.Sign) .WithTitle("This Event is overdue!") .WithDescription("The event will be released immediately (FailOnOverDueApproval configuration is off)") .WithCurrentTimestamp() .SendEmbed(Context.Channel); Event.Status = EventStatus.Approved; await ReleaseEvent(EventID); return; } } DateTimeOffset Release = DateTimeOffset.FromUnixTimeSeconds(Event.DateTimeRelease).ToOffset(TimeSpan.FromHours(BotConfiguration.StandardTimeZone)); if (!TimerService.TimerExists(Event.ReleaseTimer)) { Event.ReleaseTimer = await CreateEventTimer(ReleaseEventCallback, new Dictionary <string, string> { { "ID", Event.ID.ToString() } }, (int)Release.Subtract(DateTimeOffset.Now).TotalSeconds, TimerType.Expire); } Event.ResolveReason = Reason; Event.Status = EventStatus.Approved; await UpdateEventProposal(Event.ID); await BuildEmbed(EmojiEnum.Love) .WithTitle("Event approved for release!") .WithDescription($"Event #{Event.ID} will be released at {Release:ddd', 'MMM d 'at' hh:mm tt 'UTC'z} ({Release.Humanize()}).") .WithCurrentTimestamp() .SendDMAttachedEmbed(Context.Channel, BotConfiguration, Proposer, BuildEmbed(EmojiEnum.Love) .WithTitle("Your Event has been Approved!") .WithDescription(Event.Description) .AddField(Reason.Length > 0, "Reason: ", Reason) .AddField("Release Time:", $"{Release:ddd', 'MMM d 'at' hh:mm tt 'UTC'z}")); CommunityEventsDB.SaveChanges(); }