EmailItem.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. namespace qdr.app.studiou.orders2printpack.EmailStorage
  2. {
  3. /// <summary>
  4. /// Helper class for working with email items and their file operations.
  5. /// Provides a convenient wrapper around MetadataItem with additional functionality
  6. /// for file system operations, validation, and state management.
  7. /// </summary>
  8. public class EmailItem
  9. {
  10. #region Private Fields
  11. /// <summary>
  12. /// The underlying metadata item containing email and processing information
  13. /// </summary>
  14. private readonly MetadataItem _metadata;
  15. /// <summary>
  16. /// Base directory path where email item directories are located
  17. /// </summary>
  18. private readonly string _basePath;
  19. #endregion
  20. #region Constructor
  21. /// <summary>
  22. /// Initializes a new instance of the EmailItem class
  23. /// </summary>
  24. /// <param name="metadata">The metadata item containing email information</param>
  25. /// <param name="basePath">Base directory path for file operations</param>
  26. /// <exception cref="ArgumentNullException">Thrown when metadata or basePath is null</exception>
  27. public EmailItem(MetadataItem metadata, string basePath)
  28. {
  29. _metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
  30. _basePath = basePath ?? throw new ArgumentNullException(nameof(basePath));
  31. }
  32. #endregion
  33. #region Public Properties
  34. /// <summary>
  35. /// Gets the underlying metadata item
  36. /// </summary>
  37. public MetadataItem Metadata => _metadata;
  38. /// <summary>
  39. /// Gets the full directory path for this email item
  40. /// Combines the base path with the directory name from metadata
  41. /// </summary>
  42. public string DirectoryPath => Path.Combine(_basePath, _metadata.DirectoryName);
  43. /// <summary>
  44. /// Gets a value indicating whether the directory exists on the file system
  45. /// </summary>
  46. public bool DirectoryExists => Directory.Exists(DirectoryPath);
  47. /// <summary>
  48. /// Gets all JPG files in the email item's directory
  49. /// Returns an empty enumerable if the directory doesn't exist
  50. /// </summary>
  51. public IEnumerable<string> JpgFiles =>
  52. DirectoryExists ? Directory.GetFiles(DirectoryPath, "*.jpg") : Enumerable.Empty<string>();
  53. /// <summary>
  54. /// Gets the count of JPG files in the directory
  55. /// </summary>
  56. public int FileCount => JpgFiles.Count();
  57. /// <summary>
  58. /// Gets the total size in bytes of all JPG files in the directory
  59. /// </summary>
  60. public long TotalFileSize => JpgFiles.Sum(f => new FileInfo(f).Length);
  61. /// <summary>
  62. /// Gets a value indicating whether this item is ready for processing
  63. /// Checks that the state is Ready, directory exists, and contains files
  64. /// </summary>
  65. public bool IsReadyForProcessing =>
  66. _metadata.State == EmailStateEnum.Ready && DirectoryExists && FileCount > 0;
  67. /// <summary>
  68. /// Gets a value indicating whether this item can be reset
  69. /// Items cannot be reset while they are being processed or uploaded
  70. /// </summary>
  71. public bool CanBeReset =>
  72. _metadata.State != EmailStateEnum.Processing &&
  73. _metadata.State != EmailStateEnum.Uploading;
  74. /// <summary>
  75. /// Gets the normalized filename for the recipient (safe for file system)
  76. /// Replaces @ with _at_ and . with _dot_ to create filesystem-safe names
  77. /// </summary>
  78. public string NormalizedRecipient =>
  79. _metadata.EmailAddress.Replace("@", "_at_").Replace(".", "_dot_");
  80. #endregion
  81. #region Public Methods
  82. /// <summary>
  83. /// Generates the zip filename for this item based on recipient and timestamp
  84. /// </summary>
  85. /// <param name="timestamp">Optional timestamp to use, defaults to current time</param>
  86. /// <returns>A formatted zip filename in the format: studioufoto_{recipient}_{timestamp}.zip</returns>
  87. public string GenerateZipFileName(DateTime? timestamp = null) =>
  88. $"studioufoto_{NormalizedRecipient}_{(timestamp ?? DateTime.Now):yyyyMMdd_HHmmss}.zip";
  89. /// <summary>
  90. /// Validates that the item is in a consistent state for processing
  91. /// </summary>
  92. /// <returns>A tuple containing validation result and list of issues found</returns>
  93. public (bool IsValid, List<string> Issues) Validate()
  94. {
  95. var issues = new List<string>();
  96. // Check required email address
  97. if (string.IsNullOrEmpty(_metadata.EmailAddress))
  98. issues.Add("Email address is required");
  99. // Check directory and files existence
  100. if (!DirectoryExists)
  101. issues.Add($"Directory does not exist: {DirectoryPath}");
  102. else if (FileCount == 0)
  103. issues.Add("No JPG files found in directory");
  104. // Check required email content
  105. if (string.IsNullOrEmpty(_metadata.Subject))
  106. issues.Add("Email subject is required");
  107. if (string.IsNullOrEmpty(_metadata.Body))
  108. issues.Add("Email body is required");
  109. return (issues.Count == 0, issues);
  110. }
  111. /// <summary>
  112. /// Gets a summary of the item for display purposes
  113. /// Includes recipient, file count, current state, and associated orders
  114. /// </summary>
  115. /// <returns>A formatted summary string</returns>
  116. public string GetSummary() =>
  117. $"{_metadata.EmailAddress} - {FileCount} files, {_metadata.State}, Orders: {_metadata.Orders}";
  118. #endregion
  119. }
  120. }