notification_template.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. """Pydantic schemas for notification templates."""
  2. from datetime import datetime
  3. from enum import Enum
  4. from pydantic import BaseModel, Field
  5. class EventType(str, Enum):
  6. """Supported notification event types."""
  7. PRINT_START = "print_start"
  8. PRINT_COMPLETE = "print_complete"
  9. PRINT_FAILED = "print_failed"
  10. PRINT_STOPPED = "print_stopped"
  11. PRINT_PROGRESS = "print_progress"
  12. PRINTER_OFFLINE = "printer_offline"
  13. PRINTER_ERROR = "printer_error"
  14. FILAMENT_LOW = "filament_low"
  15. MAINTENANCE_DUE = "maintenance_due"
  16. AMS_HUMIDITY_HIGH = "ams_humidity_high"
  17. AMS_TEMPERATURE_HIGH = "ams_temperature_high"
  18. TEST = "test"
  19. # Available variables for each event type
  20. EVENT_VARIABLES: dict[str, list[str]] = {
  21. "print_start": ["printer", "filename", "estimated_time", "timestamp", "app_name"],
  22. "print_complete": [
  23. "printer",
  24. "filename",
  25. "duration",
  26. "filament_grams",
  27. "finish_photo_url",
  28. "timestamp",
  29. "app_name",
  30. ],
  31. "print_failed": ["printer", "filename", "duration", "reason", "finish_photo_url", "timestamp", "app_name"],
  32. "print_stopped": ["printer", "filename", "duration", "finish_photo_url", "timestamp", "app_name"],
  33. "print_progress": ["printer", "filename", "progress", "remaining_time", "timestamp", "app_name"],
  34. "printer_offline": ["printer", "timestamp", "app_name"],
  35. "printer_error": ["printer", "error_type", "error_detail", "timestamp", "app_name"],
  36. "filament_low": ["printer", "slot", "remaining_percent", "color", "timestamp", "app_name"],
  37. "maintenance_due": ["printer", "items", "timestamp", "app_name"],
  38. "ams_humidity_high": ["printer", "ams_label", "humidity", "threshold", "timestamp", "app_name"],
  39. "ams_temperature_high": ["printer", "ams_label", "temperature", "threshold", "timestamp", "app_name"],
  40. "test": ["app_name", "timestamp"],
  41. # Queue notifications
  42. "queue_job_added": ["job_name", "target", "timestamp", "app_name"],
  43. "queue_job_assigned": ["job_name", "printer", "target_model", "timestamp", "app_name"],
  44. "queue_job_started": ["printer", "job_name", "estimated_time", "timestamp", "app_name"],
  45. "queue_job_waiting": ["job_name", "target_model", "waiting_reason", "timestamp", "app_name"],
  46. "queue_job_skipped": ["printer", "job_name", "reason", "timestamp", "app_name"],
  47. "queue_job_failed": ["printer", "job_name", "reason", "timestamp", "app_name"],
  48. "queue_completed": ["completed_count", "timestamp", "app_name"],
  49. }
  50. # Sample data for previewing templates
  51. SAMPLE_DATA: dict[str, dict[str, str]] = {
  52. "print_start": {
  53. "printer": "Bambu X1C",
  54. "filename": "Benchy.3mf",
  55. "estimated_time": "1h 23m",
  56. "timestamp": "2024-01-15 14:30",
  57. "app_name": "Bambuddy",
  58. },
  59. "print_complete": {
  60. "printer": "Bambu X1C",
  61. "filename": "Benchy.3mf",
  62. "duration": "1h 18m",
  63. "filament_grams": "15.2",
  64. "finish_photo_url": "/api/v1/archives/123/photos/finish_20240115_154800_abc12345.jpg",
  65. "timestamp": "2024-01-15 15:48",
  66. "app_name": "Bambuddy",
  67. },
  68. "print_failed": {
  69. "printer": "Bambu X1C",
  70. "filename": "Benchy.3mf",
  71. "duration": "0h 45m",
  72. "reason": "Filament runout",
  73. "finish_photo_url": "/api/v1/archives/123/photos/finish_20240115_151500_def67890.jpg",
  74. "timestamp": "2024-01-15 15:15",
  75. "app_name": "Bambuddy",
  76. },
  77. "print_stopped": {
  78. "printer": "Bambu X1C",
  79. "filename": "Benchy.3mf",
  80. "duration": "0h 30m",
  81. "finish_photo_url": "/api/v1/archives/123/photos/finish_20240115_150000_ghi11223.jpg",
  82. "timestamp": "2024-01-15 15:00",
  83. "app_name": "Bambuddy",
  84. },
  85. "print_progress": {
  86. "printer": "Bambu X1C",
  87. "filename": "Benchy.3mf",
  88. "progress": "50",
  89. "remaining_time": "0h 41m",
  90. "timestamp": "2024-01-15 15:00",
  91. "app_name": "Bambuddy",
  92. },
  93. "printer_offline": {
  94. "printer": "Bambu X1C",
  95. "timestamp": "2024-01-15 14:30",
  96. "app_name": "Bambuddy",
  97. },
  98. "printer_error": {
  99. "printer": "Bambu X1C",
  100. "error_type": "AMS Error",
  101. "error_detail": "Filament slot 1 jammed",
  102. "timestamp": "2024-01-15 14:30",
  103. "app_name": "Bambuddy",
  104. },
  105. "filament_low": {
  106. "printer": "Bambu X1C",
  107. "slot": "1",
  108. "remaining_percent": "15",
  109. "color": "Black PLA",
  110. "timestamp": "2024-01-15 14:30",
  111. "app_name": "Bambuddy",
  112. },
  113. "maintenance_due": {
  114. "printer": "Bambu X1C",
  115. "items": "• Nozzle cleaning (OVERDUE)\n• Carbon rod lubrication (Soon)",
  116. "timestamp": "2024-01-15 14:30",
  117. "app_name": "Bambuddy",
  118. },
  119. "ams_humidity_high": {
  120. "printer": "Bambu X1C",
  121. "ams_label": "AMS-A",
  122. "humidity": "75",
  123. "threshold": "60",
  124. "timestamp": "2024-01-15 14:30",
  125. "app_name": "Bambuddy",
  126. },
  127. "ams_temperature_high": {
  128. "printer": "Bambu X1C",
  129. "ams_label": "AMS-A",
  130. "temperature": "42",
  131. "threshold": "35",
  132. "timestamp": "2024-01-15 14:30",
  133. "app_name": "Bambuddy",
  134. },
  135. "test": {
  136. "app_name": "Bambuddy",
  137. "timestamp": "2024-01-15 14:30",
  138. },
  139. # Queue notifications
  140. "queue_job_added": {
  141. "job_name": "Benchy.3mf",
  142. "target": "Bambu X1C",
  143. "timestamp": "2024-01-15 14:30",
  144. "app_name": "Bambuddy",
  145. },
  146. "queue_job_assigned": {
  147. "job_name": "Benchy.3mf",
  148. "printer": "Bambu X1C #1",
  149. "target_model": "X1C",
  150. "timestamp": "2024-01-15 14:30",
  151. "app_name": "Bambuddy",
  152. },
  153. "queue_job_started": {
  154. "printer": "Bambu X1C",
  155. "job_name": "Benchy.3mf",
  156. "estimated_time": "1h 23m",
  157. "timestamp": "2024-01-15 14:30",
  158. "app_name": "Bambuddy",
  159. },
  160. "queue_job_waiting": {
  161. "job_name": "Benchy.3mf",
  162. "target_model": "X1C",
  163. "waiting_reason": "Printer1 (needs PLA)",
  164. "timestamp": "2024-01-15 14:30",
  165. "app_name": "Bambuddy",
  166. },
  167. "queue_job_skipped": {
  168. "printer": "Bambu X1C",
  169. "job_name": "Benchy.3mf",
  170. "reason": "Previous print failed",
  171. "timestamp": "2024-01-15 14:30",
  172. "app_name": "Bambuddy",
  173. },
  174. "queue_job_failed": {
  175. "printer": "Bambu X1C",
  176. "job_name": "Benchy.3mf",
  177. "reason": "Upload failed: connection timeout",
  178. "timestamp": "2024-01-15 14:30",
  179. "app_name": "Bambuddy",
  180. },
  181. "queue_completed": {
  182. "completed_count": "5",
  183. "timestamp": "2024-01-15 18:30",
  184. "app_name": "Bambuddy",
  185. },
  186. }
  187. class NotificationTemplateBase(BaseModel):
  188. """Base schema for notification templates."""
  189. title_template: str = Field(..., min_length=1, max_length=200)
  190. body_template: str = Field(..., min_length=1, max_length=2000)
  191. class NotificationTemplateUpdate(BaseModel):
  192. """Schema for updating a notification template."""
  193. title_template: str | None = Field(default=None, min_length=1, max_length=200)
  194. body_template: str | None = Field(default=None, min_length=1, max_length=2000)
  195. class NotificationTemplateResponse(NotificationTemplateBase):
  196. """Schema for notification template API responses."""
  197. id: int
  198. event_type: str
  199. name: str
  200. is_default: bool
  201. created_at: datetime
  202. updated_at: datetime
  203. class Config:
  204. from_attributes = True
  205. class TemplateVariableInfo(BaseModel):
  206. """Information about a template variable."""
  207. name: str
  208. description: str
  209. class EventVariablesResponse(BaseModel):
  210. """Response for available variables per event type."""
  211. event_type: str
  212. event_name: str
  213. variables: list[str]
  214. class TemplatePreviewRequest(BaseModel):
  215. """Request to preview a template with sample data."""
  216. event_type: str
  217. title_template: str
  218. body_template: str
  219. class TemplatePreviewResponse(BaseModel):
  220. """Response with rendered template preview."""
  221. title: str
  222. body: str