123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- using Comal.Classes;
- using InABox.Core;
- using InABox.Database;
- using InABox.Scripting;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Serialization;
- using System.Text;
- using System.Threading.Tasks;
- namespace PRS.Shared.Events;
- public class ScheduledEventDayOfWeek : BaseObject
- {
- [EditorSequence(1)]
- [Editable(Editable.Disabled)]
- public DayOfWeek DayOfWeek { get; set; }
- [EditorSequence(2)]
- [TimeOfDayEditor]
- public TimeSpan StartTime { get; set; } = TimeSpan.Zero;
- [EditorSequence(3)]
- [TimeOfDayEditor]
- public TimeSpan EndTime { get; set; } = new TimeSpan(23, 59, 59);
- [EditorSequence(4)]
- public bool Enabled { get; set; } = true;
- public ScheduledEventDayOfWeek()
- {
- }
- public ScheduledEventDayOfWeek(DayOfWeek dayOfWeek)
- {
- DayOfWeek = dayOfWeek;
- }
- static ScheduledEventDayOfWeek()
- {
- DefaultColumns.Add<ScheduledEventDayOfWeek>(x => x.DayOfWeek);
- DefaultColumns.Add<ScheduledEventDayOfWeek>(x => x.StartTime);
- DefaultColumns.Add<ScheduledEventDayOfWeek>(x => x.EndTime);
- }
- }
- /// <summary>
- /// Properties class to manage the timing of a scheduled event.
- /// </summary>
- /// <remarks>
- /// <para>
- /// This is fairly complex. First, we have the <see cref="Frequency"/> and <see cref="Period"/> properties. These function as expected.
- /// If <see cref="Frequency"/> is 3, and <see cref="Period"/> is <see cref="SchedulePeriod.Hour"/>, the event happens every three hours. Similarly,
- /// if <see cref="Frequency"/> is 4, and <see cref="Period"/> is <see cref="SchedulePeriod.Month"/>, the event happens every four months.
- /// </para>
- /// <para>
- /// However, the other properties are dependent on <see cref="Period"/>. If <see cref="Period"/> is <see cref="SchedulePeriod.Minute"/>,
- /// <see cref="SchedulePeriod.Hour"/> or <see cref="SchedulePeriod.Day"/> (that is, anything a day or smaller), the <see cref="DayOfWeekSettings"/>
- /// is used, which says which days of the week the schedule should occur, and at what time on those days.
- /// If the period is <see cref="SchedulePeriod.Day"/>, then only the <see cref="ScheduledEventDayOfWeek.StartTime"/> is used, and the event occurs
- /// at that time. Otherwise, the event occurs at regular intervals according to the frequency and period, beginning at
- /// <see cref="ScheduledEventDayOfWeek.StartTime"/> and running until <see cref="ScheduledEventDayOfWeek.EndTime"/>.
- /// </para>
- /// <para>
- /// Alternatively, if the period is greater than a day, <see cref="NextSchedule"/> is used, and whenever the schedule executes, it is updated by the
- /// frequency and period <i>from the due date</i>, and not from when the schedule actually occurred.
- /// </para>
- /// </remarks>
- public class ScheduledEventProperties : BaseObject
- {
- [EditorSequence(1)]
- public int Frequency { get; set; } = 1;
- [EditorSequence(2)]
- public SchedulePeriod Period { get; set; } = SchedulePeriod.Hour;
- [EditorSequence(3)]
- public DateTime NextSchedule { get; set; }
- [EditorSequence(4)]
- [Editable(Editable.Disabled)]
- [TimestampEditor]
- public DateTime LastExecution { get; set; }
- [EmbeddedListEditor(typeof(ScheduledEventDayOfWeek), AddRows = false)]
- public List<ScheduledEventDayOfWeek> DayOfWeekSettings { get; set; } = new()
- {
- new(DayOfWeek.Monday),
- new(DayOfWeek.Tuesday),
- new(DayOfWeek.Wednesday),
- new(DayOfWeek.Thursday),
- new(DayOfWeek.Friday),
- new(DayOfWeek.Saturday),
- new(DayOfWeek.Sunday),
- };
- [OnDeserializing]
- private void OnDeserialisingMethod(StreamingContext context)
- {
- DayOfWeekSettings.Clear();
- }
- }
- public class ScheduledEvent : IEvent<ScheduledEventDataModel>, IPropertiesEvent<ScheduledEventProperties>
- {
- public ScheduledEventProperties Properties { get; set; } = new();
- public IEventDataModelDefinition DataModelDefinition()
- {
- return new ScheduledEventDataModelDefinition();
- }
- public Notification GenerateNotification(ScheduledEventDataModel model)
- {
- var notification = new Notification();
- notification.Title = $"Scheduled event {model.Event.Code}: {model.Event.Description} has run.";
- notification.Description = $"Scheduled event {model.Event.Code}: {model.Event.Description} has run.";
- return notification;
- }
- public ScheduledEventProperties GetProperties()
- {
- return Properties;
- }
- public void SetProperties(ScheduledEventProperties properties)
- {
- Properties = properties;
- }
- }
- public class ScheduledEventDataModelDefinition : IEventDataModelDefinition
- {
- public IEventVariable? GetVariable(string name)
- {
- return null;
- }
- public IEnumerable<IEventVariable> GetVariables()
- {
- return [];
- }
- }
- public class ScheduledEventDataModel(Event ev) : IEventDataModel
- {
- public Event Event { get; set; } = ev;
- public bool TryGetVariable(string name, out object? value)
- {
- value = null;
- return false;
- }
- }
- #region Triggers
- [Caption("Custom Script")]
- public class ScriptScheduledEventTrigger : IEventTrigger<ScheduledEvent, ScheduledEventDataModel>
- {
- public string Description => "Custom Script";
- private ScriptDocument? _scriptDocument;
- private ScriptDocument? ScriptDocument
- {
- get
- {
- if(_scriptDocument is null && Script is not null)
- {
- _scriptDocument = new(Script);
- _scriptDocument.Compile();
- }
- return _scriptDocument;
- }
- }
- private string? _script;
- public string? Script
- {
- get => _script;
- set
- {
- if(_script != value)
- {
- _script = value;
- _scriptDocument = null;
- }
- }
- }
- public IEnumerable<string> ReferencedVariables => [];
- public string DefaultScript()
- {
- return @"using PRS.Shared.Events;
- public class Module
- {
- public bool Check(ScheduledEventDataModel model)
- {
- // Return true if the requirements are met for this event trigger.
- return true;
- }
- }";
- }
- public bool Check(ScheduledEventDataModel dataModel)
- {
- if (ScriptDocument is null) return false;
- return ScriptDocument.Execute(methodname: "Check", parameters: [dataModel]);
- }
- }
- #endregion
- #region Actions
- [Caption("Custom Script")]
- public class ScriptScheduledEventAction : IEventAction<ScheduledEvent>
- {
- private ScriptDocument? _scriptDocument;
- private ScriptDocument? ScriptDocument
- {
- get
- {
- if(_scriptDocument is null && Script is not null)
- {
- _scriptDocument = new(Script);
- _scriptDocument.SetValue("Result", null);
- _scriptDocument.Compile();
- }
- return _scriptDocument;
- }
- }
- private string? _script;
- public string? Script
- {
- get => _script;
- set
- {
- if(_script != value)
- {
- _script = value;
- _scriptDocument = null;
- }
- }
- }
- public IEnumerable<string> ReferencedVariables => [];
- public string Description => "Custom Script";
- public string DefaultScript()
- {
- return @"using PRS.Shared.Events;
- public class Module
- {
- public object? Result { get; set; }
- public bool Execute(ScheduledEventDataModel model)
- {
- // Do anything you want, and then save return-value to 'Result', or leave it as 'null' if no return value is needed.
- return true;
- }
- }";
- }
- public object? Execute(IEventDataModel dataModel)
- {
- if (ScriptDocument is null) return null;
- var model = dataModel.RootModel<ScheduledEventDataModel>();
- if(ScriptDocument.Execute(methodname: "Execute", parameters: [model]))
- {
- return ScriptDocument.GetValue("Result");
- }
- else
- {
- return null;
- }
- }
- }
- #endregion
|