PosterEngine.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using InABox.Clients;
  2. using InABox.Configuration;
  3. using InABox.Core.Postable;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. namespace InABox.Core
  9. {
  10. public interface IPosterEngine<TPostable>
  11. where TPostable : Entity, IPostable, IRemotable, IPersistent, new()
  12. {
  13. bool Process(IEnumerable<TPostable> posts);
  14. }
  15. public interface IPosterEngine<TPostable, TPoster, TSettings> : IPosterEngine<TPostable>
  16. where TPostable : Entity, IPostable, IRemotable, IPersistent, new()
  17. where TPoster : IPoster<TPostable, TSettings>
  18. where TSettings : PosterSettings, new()
  19. {
  20. }
  21. public abstract class PosterEngine<TPostable, TPoster, TSettings> : IPosterEngine<TPostable, TPoster, TSettings>
  22. where TPostable : Entity, IPostable, IRemotable, IPersistent, new()
  23. where TPoster : IPoster<TPostable, TSettings>
  24. where TSettings : PosterSettings, new()
  25. {
  26. protected static TPoster Poster = GetPoster();
  27. private static Type[]? _posters;
  28. private static TPoster GetPoster()
  29. {
  30. _posters ??= CoreUtils.TypeList(
  31. AppDomain.CurrentDomain.GetAssemblies(),
  32. x => x.IsClass
  33. && !x.IsAbstract
  34. && !x.IsGenericType
  35. && x.HasInterface(typeof(IPoster<,>))
  36. ).ToArray();
  37. var type = _posters.Where(x => typeof(TPoster).IsAssignableFrom(x)).FirstOrDefault()
  38. ?? throw new Exception($"No poster of type {typeof(TPoster)}.");
  39. return (TPoster)Activator.CreateInstance(type);
  40. }
  41. protected static TSettings GetSettings()
  42. {
  43. return PosterUtils.LoadPosterSettings<TPostable, TSettings>();
  44. }
  45. protected static void SaveSettings(TSettings settings)
  46. {
  47. PosterUtils.SavePosterSettings<TPostable, TSettings>(settings);
  48. }
  49. /// <summary>
  50. /// Returns the <see cref="TSettings.Script"/>, if <see cref="TSettings.ScriptEnabled"/> is <see langword="true"/>;
  51. /// otherwise, returns <see langword="null"/>.
  52. /// </summary>
  53. protected static string? GetScript()
  54. {
  55. var settings = GetSettings();
  56. return settings.ScriptEnabled ? settings.Script : null;
  57. }
  58. protected abstract bool DoProcess(IEnumerable<TPostable> posts);
  59. public bool Process(IEnumerable<TPostable> posts)
  60. {
  61. var list = posts.ToList();
  62. if(list.Any(x => x.PostedStatus == PostedStatus.Posted))
  63. {
  64. throw new RepostedException();
  65. }
  66. try
  67. {
  68. var success = DoProcess(list);
  69. if (success)
  70. {
  71. foreach (var post in list)
  72. {
  73. post.Posted = DateTime.Now;
  74. post.PostedStatus = PostedStatus.Posted;
  75. }
  76. new Client<TPostable>().Save(list, "Posted by user.");
  77. }
  78. else
  79. {
  80. foreach (var post in list)
  81. {
  82. post.PostedStatus = PostedStatus.PostFailed;
  83. }
  84. new Client<TPostable>().Save(list, "Post failed by user.");
  85. }
  86. return success;
  87. }
  88. catch(Exception e)
  89. {
  90. Logger.Send(LogType.Error, "", $"Post Failed: {CoreUtils.FormatException(e)}");
  91. foreach (var post in list)
  92. {
  93. post.PostedStatus = PostedStatus.PostFailed;
  94. }
  95. new Client<TPostable>().Save(list, "Post failed by user.");
  96. throw;
  97. }
  98. }
  99. }
  100. }