using InABox.Clients; using InABox.Configuration; using InABox.Core.Postable; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace InABox.Core { public interface IPosterEngine where TPostable : Entity, IPostable, IRemotable, IPersistent, new() { bool Process(IEnumerable posts); } public interface IPosterEngine : IPosterEngine where TPostable : Entity, IPostable, IRemotable, IPersistent, new() where TPoster : IPoster where TSettings : PosterSettings, new() { } public abstract class PosterEngine : IPosterEngine where TPostable : Entity, IPostable, IRemotable, IPersistent, new() where TPoster : IPoster where TSettings : PosterSettings, new() { protected static TPoster Poster = GetPoster(); private static Type[]? _posters; private static TPoster GetPoster() { _posters ??= CoreUtils.TypeList( AppDomain.CurrentDomain.GetAssemblies(), x => x.IsClass && !x.IsAbstract && !x.IsGenericType && x.HasInterface(typeof(IPoster<,>)) ).ToArray(); var type = _posters.Where(x => typeof(TPoster).IsAssignableFrom(x)).FirstOrDefault() ?? throw new Exception($"No poster of type {typeof(TPoster)}."); return (TPoster)Activator.CreateInstance(type); } protected static TSettings GetSettings() { return PosterUtils.LoadPosterSettings(); } protected static void SaveSettings(TSettings settings) { PosterUtils.SavePosterSettings(settings); } /// /// Returns the , if is ; /// otherwise, returns . /// protected static string? GetScript() { var settings = GetSettings(); return settings.ScriptEnabled ? settings.Script : null; } protected abstract bool DoProcess(IEnumerable posts); public bool Process(IEnumerable posts) { var list = posts.AsList(); if(list.Any(x => x.PostedStatus == PostedStatus.Posted)) { throw new RepostedException(); } try { var success = DoProcess(list); if (success) { foreach (var post in list) { post.Posted = DateTime.Now; post.PostedStatus = PostedStatus.Posted; } new Client().Save(list, "Posted by user."); } else { foreach (var post in list) { post.PostedStatus = PostedStatus.PostFailed; } new Client().Save(list, "Post failed by user."); } return success; } catch(Exception e) { Logger.Send(LogType.Error, "", $"Post Failed: {CoreUtils.FormatException(e)}"); foreach (var post in list) { post.PostedStatus = PostedStatus.PostFailed; } new Client().Save(list, "Post failed by user."); throw; } } } }