import std/[times, osproc], smtp import ../models/reminder, ../models/user, datetime proc setFutureSendDate(reminderId: int) = var reminder: Reminder reminder = getReminderById(reminderId) var newSendDate: DateTime case reminder.repeatFreq: of "day": newSendDate = now() + 1.days reminder.sendDate = $format(newSendDate, "yyyy-MM-dd") updateReminderSendDate(reminder) clearAllReminders() of "week": newSendDate = nextWeekday(reminder.weeklyOn) reminder.sendDate = $format(newSendDate, "yyyy-MM-dd") updateReminderSendDate(reminder) clearAllReminders() of "month": if reminder.monthlyOnDay > 0: #create DateTime with current month and year and reminder.monthlyOnDay newSendDate = dateTime(year(now()), month(now()), reminder.monthlyOnDay) echo newSendDate #add 1 month only if monthlyOnDay hasn't occured in current month yet. echo reminder.monthlyOnDay echo monthDay(now()) if reminder.monthlyOnDay < monthDay(now()): newSendDate = newSendDate + 1.months echo newSendDate reminder.sendDate = $format(newSendDate, "yyyy-MM-dd") echo reminder.sendDate updateReminderSendDate(reminder) clearAllReminders() else: #monthly on week number and weekday. e.g. "third thursday of every month". newSendDate = nextMonthlyOnWeekdayOfWeek($reminder.monthlyOnWeekday, $reminder.monthlyOnWeek) reminder.sendDate = $format(newSendDate, "yyyy-MM-dd") updateReminderSendDate(reminder) clearAllReminders() of "year": #yearly on month and day. #string zeros (db artifacts) have a length of 1... if reminder.yearlyOnMonth.len() > 1: newSendDate = nextYearlyDate(reminder.yearlyOnMonth, reminder.yearlyOnDay) reminder.sendDate = $format(newSendDate, "yyyy-MM-dd") updateReminderSendDate(reminder) clearAllReminders() #yearly on weekday of week of month. e.g. third thursday of november of each year. else: newSendDate = nextYearlyOnWeekdayOfWeekOfMonth($reminder.yearlyOnWeekday, $reminder.yearlyOnWeek, $reminder.yearlyOnMonth2) reminder.sendDate = $format(newSendDate, "yyyy-MM-dd") updateReminderSendDate(reminder) clearAllReminders() else: echo "Invalid value for reminder.repeatFreq in setFutureSendDate()" proc sendEmail(reminderMsg: string) = let userEmailAddress = getEmailByUserId("1") let headers = @[("From", "mailer@itwrx.org")] let msg = createMessage("Reminder from Forget-Me-Not", reminderMsg, @[userEmailAddress], mCc = @[""], otherHeaders = headers) {.cast(raises: []).}: let smtpConn = newSmtp(debug=false) smtpConn.connect("email.itwrx.org", Port 587) smtpConn.startTls() smtpConn.auth("mailer@itwrx.org", ".AQ8u((xB(AgZh^a`jEJ~W~{0Eq?fd$") #loop through email messages and send to reuse connection? smtpConn.sendmail("mailer@itwrx.org", @[userEmailAddress], $msg) #manually closing not necessary? smtpConn.close() proc sendXMPP(reminderMsg: string) = var output: string var status: int (output, status) = execCmdEx("xmppc -m message chat itwrx@sec-chat.itwrx.org \"" & reminderMsg & "\"") if status != 0: #log this later instead. echo output echo "error sending XMPP msg" #send reminders that haven't been sent yet and set new sendDate (if repeating). proc sendReminders*() = let nowDT = now() let reminders = getAllReminders() for reminder in reminders: let sendDateDTString = $reminder.sendDate & " " & $reminder.sendTimeHr & ":" & $reminder.sendTimeMin & ":" & $reminder.sendTimeAmPm #single digits for minutes, as db send_time_min is integer and won't use "00", which results in runtime parse error. let sendDateDT = parse(sendDateDTString, "yyyy-M-d h:m:tt") #if sendDate is not in the future, it hasn't been sent yet (we are changing sendDate to future date during each send) and needs to be sent. if sendDateDT <= nowDT: #send reminder notification case reminder.notifyVia: of "email": sendEmail(reminder.message) of "xmpp": sendXMPP(reminder.message) else: sendXMPP(reminder.message) sendEmail(reminder.message) if reminder.repeats == 1: setFutureSendDate(reminder.id) else: deleteReminder(reminder.id) clearAllReminders()