From 6fe101f220c459ad5d684527c820d906be19eb1e Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Sat, 22 Feb 2014 18:47:13 -0600 Subject: [PATCH] Working draft of the server side. Testing files. --- .../NurseryScheduleServlet.groovy | 132 ++++++++++++++ src/test/make_template.groovy | 34 ++++ src/test/nursery-schedule-2013-10-01.txt | 42 +++++ src/test/test.html | 165 ++++++++++++++++++ src/test/test.json | 2 + src/test/test.template | 9 + 6 files changed, 384 insertions(+) create mode 100644 src/java/com/jdbernard/nurseryschedule/NurseryScheduleServlet.groovy create mode 100644 src/test/make_template.groovy create mode 100644 src/test/nursery-schedule-2013-10-01.txt create mode 100644 src/test/test.html create mode 100644 src/test/test.json create mode 100644 src/test/test.template diff --git a/src/java/com/jdbernard/nurseryschedule/NurseryScheduleServlet.groovy b/src/java/com/jdbernard/nurseryschedule/NurseryScheduleServlet.groovy new file mode 100644 index 0000000..9f14f3a --- /dev/null +++ b/src/java/com/jdbernard/nurseryschedule/NurseryScheduleServlet.groovy @@ -0,0 +1,132 @@ +package com.jdbernard.nurseryschedule + +import com.jdbernard.util.SmartConfig +import groovy.json.JsonBuilder +import groovy.json.JsonException +import groovy.json.JsonSlurper +import groovy.text.SimpleTemplateEngine +import java.util.Calendar +import java.util.regex.Matcher +import javax.servlet.ServletConfig +import javax.servlet.ServletException +import javax.servlet.http.HttpServlet +import javax.servlet.http.HttpServletRequest +import javax.servlet.http.HttpServletResponse +import javax.servlet.http.HttpSession + +import static java.util.Calendar.* +import static javax.servlet.http.HttpServletResponse.* + +public class NurseryScheduleServlet extends HttpServlet { + + /// This service currently only supports one user. + private String username + private String password + private String outputDirectory + + private static SimpleDateFormat dataDateFormat = + new SimpleDateFormat("yyyy-MM-dd") + private static SimpleDateFormat displayDateFormat = + new SimpleDateFormat("MMM dd") + + void init(ServletConfig config) { + this.username = config.getInitParameter("username") + this.password = config.getInitParameter("password") + this.outputDirectory = config.getInitParameter("outputDirectory") } + + void doPost(HttpServletRequest request, HttpServletResponse response) { + + HttpSession session = request.getSession(true); + + /// If the user is posting to `/login` then let's try to authenticate + /// them. We don't care about the state of the existing session. + if (request.servletPath == '/login') { + + /// Parse the username/password from the request. + def requestBody + try { requestBody = new JsonSlurper().parse(request.reader) } + catch (JsonException jsone) { + response.status = SC_BAD_REQUEST + return } + + /// If no username or password are configured we cannot + /// authenticate the user. + if (!password || !username) { + response.status = SC_UNAUTHORIZED + return } + + /// If the username or password do not match, deny the request. + if (username != requestBody.username || + password != requestBody.password) { + response.status = SC_UNAUTHORIZED + return } + + response.status = SC_OK + session.setAttribute('authenticated', 'true') + session.setAttribute('username', requestBody.username) + writeJSON([status: "ok"], response) + return } + + /// The other endpoints require the user to be authenticated. + if (!((boolean)session.getAttribute('authenticated'))) { + response.status = SC_UNAUTHORIZED + return } + + switch (request.servletPath) { + case ~ '/make-schedule': + + /// Parse the request body. + def data + try { data = new JsonSlurper().parse(request.reader) } + catch (JsonException jsone) { + response.status = SC_BAD_REQUEST + return } + + /// Calculate dates and modify the schedule data to include + /// them. + def cal = Calendar.getInstance() + cal.time = dataDateFormat.parse(data.date) + int month = cal.get(MONTH) + cal.set(HOUR_OF_DAY, 0) + cal.set(MINUTE, 0) + cal.set(SECOND, 0) + cal.set(MILLISECOND, 0) + + ['first', 'second', 'third', 'fourth', 'fifth'].eachWithIndex + { dayNum, idx -> + /// Set the sunday + cal.set(DAY_OF_WEEK, SUNDAY) + cal.set(DAY_OF_WEEK_IN_MONTH, idx + 1) + if (cal.get(MONTH) == month) + data.sundays[dayNum].date = displayDateFormat.format(cal.time) + + /// Set the wednesday. Note that we have to reformat the + /// input data from {"first": ["PersonA", "PersonB"]} to + /// {"date": "Oct. 6", "volunteers": ["PersonA", PersonB"]} + def volunteers = data.wednesdays[dayNum] + data.wednesdays[dayNum] = [:] + data.wednesdays[dayNum].volunteers = volunteers + + if (cal.get(MONTH) == month) + data.wednesdays[dayNum].date = + displayDateFormat.format(cal.time) } + + cal.set(DAY_OF_WEEK_IN_MONTH, 2) + data.sundays['second'].date = displayDateFormat.format(cal.time) + + /// Build the resulting page. + def engine = new SimpleTemplateEngine() + def scheduleTemplate = engine.createTemplate( + this.getClass().getResource('schedule.template')) + def output = scheduleTemplate.make(data) + + /// Write the results to file. + new File(outputDirectory, data.date + ".html").text = output + response.status = SC_OK + + default: + response.status = SC_NOT_FOUND + return + } + } +} diff --git a/src/test/make_template.groovy b/src/test/make_template.groovy new file mode 100644 index 0000000..59bea9b --- /dev/null +++ b/src/test/make_template.groovy @@ -0,0 +1,34 @@ +import com.jdbernard.util.LightOptionParser +import groovy.json.JsonSlurper +import groovy.text.SimpleTemplateEngine + +def cli = [ + 't': [longName: 'template', arguments: 1], + 'd': [longName: 'data', arguments: 1], + 'o': [longName: 'output', arguments: 1]] + +def opts = LightOptionParser.parseOptions(cli, args as List) + +def templateFile, dataFile, outputFile + +if (opts.t) templateFile = new File(opts.t) +if (opts.d) dataFile = new File(opts.d) +if (opts.o) outputFile = new File(opts.o) + +if (!templateFile || !templateFile.exists() || !templateFile.isFile()) { + println "Template file is not specified or does not exist." + return -1 } + +if (!dataFile || !dataFile.exists() || !dataFile.isFile()) { + println "Data file is not specified or does not exist." + return -1 } + +if (!outputFile) { + println "Output file is not specified." + return -1 } + +def engine = new SimpleTemplateEngine() +def binding = new JsonSlurper().parseText(dataFile.text) +def template = engine.createTemplate(templateFile.text).make(binding) + +outputFile.text = template.toString() diff --git a/src/test/nursery-schedule-2013-10-01.txt b/src/test/nursery-schedule-2013-10-01.txt new file mode 100644 index 0000000..ec5ba84 --- /dev/null +++ b/src/test/nursery-schedule-2013-10-01.txt @@ -0,0 +1,42 @@ +{"date":"2013-10-01", + "sundays":{ + "first":{ + "date": "Oct. 6th", + "toddlers":["Sara Bernard","Priscilla Reid","Becca Torres"], + "infants":["Latonya Kirton","Susan Vacca","Brandie Kristoff"], + "pm":["Susan Miller","Pamala Green"]}, + "second":{ + "date": "Oct. 13th", + "toddlers":["Sara Bernard","Priscilla Reid","Maria Almazan"], + "infants":["Latonya Kirton","Susan Vacca","Rebecca Dombroski"], + "pm":["Zoe Torres","Hannah Torres"]}, + "third":{ + "date": "Oct. 20th", + "toddlers":["Sara Bernard","Priscilla Reid","Delia Borrego"], + "infants":["Latonya Kirton","Susan Vacca","Deborah McDonald"], + "pm":["Jeanie Nelson","Alayna Robert"]}, + "fourth":{ + "date": "Oct. 27th", + "toddlers":["Sara Bernard","Priscilla Reid","Maria Almazan"], + "infants":["Latonya Kirton","Susan Vacca","Crystal Johnson"], + "pm":["Deidra Dawson","Shekinah Dawson"]}, + "fifth":{ + "toddlers":["Sara Bernard","Priscilla Reid","Julie Froese"], + "infants":["Latonya Kirton","Susan Vacca"], + "pm":[]}}, + "wednesdays":{ + "first": { + "date": "Oct. 3rd", + "volunteers": ["Courtney or Bryan Bootka","Gabby Galvez"]}, + "second": { + "date": "Oct. 10th", + "volunteers": ["Reeta or Lionel Aguilar","Stephanie Langley"]}, + "third": { + "date": "Oct. 17th", + "volunteers": ["Christina Grooms","Lanell Hanson"]}, + "fourth": { + "date": "Oct. 24th", + "volunteers": ["Cassie Hernandez"]}, + "fifth": { + "date": "Oct. 31st", + "volunteers": ["Regina Noble","Vita Sharpe"]}}} diff --git a/src/test/test.html b/src/test/test.html new file mode 100644 index 0000000..7d4071d --- /dev/null +++ b/src/test/test.html @@ -0,0 +1,165 @@ + + + + + + +
+ +
+

First Sunday, Oct. 6th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Becca Torres
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Brandie Kristoff
  • +
+
+
+
+
Evening Service
+
    +
  • Susan Miller
  • +
  • Pamala Green
  • +
+
+
+ +
+

Second Sunday, Oct. 13th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Maria Almazan
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Rebecca Dombroski
  • +
+
+
+
+
Evening Service
+
    +
  • Zoe Torres
  • +
  • Hannah Torres
  • +
+
+
+ +
+

Third Sunday, Oct. 20th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Delia Borrego
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Deborah McDonald
  • +
+
+
+
+
Evening Service
+
    +
  • Jeanie Nelson
  • +
  • Alayna Robert
  • +
+
+
+ +
+

Fourth Sunday, Oct. 27th

+
+
+
Toddlers
+
    +
  • Sara Bernard
  • +
  • Priscilla Reid
  • +
  • Maria Almazan
  • +
+
+
+
Infants
+
    +
  • Latonya Kirton
  • +
  • Susan Vacca
  • +
  • Crystal Johnson
  • +
+
+
+
+
Evening Service
+
    +
  • Deidra Dawson
  • +
  • Shekinah Dawson
  • +
+
+
+ +
+ +
+
+

First Wednesday, Oct. 3rd

+
    +
  • Courtney or Bryan Bootka
  • +
  • Gabby Galvez
  • +
+
+
+

Second Wednesday, Oct. 10th

+
    +
  • Reeta or Lionel Aguilar
  • +
  • Stephanie Langley
  • +
+
+
+

Third Wednesday, Oct. 17th

+
    +
  • Christina Grooms
  • +
  • Lanell Hanson
  • +
+
+
+

Fourth Wednesday, Oct. 24th

+
    +
  • Cassie Hernandez
  • +
+
+
+

Fifth Wednesday, Oct. 31st

+
    +
  • Regina Noble
  • +
  • Vita Sharpe
  • +
+
+ +
+ + diff --git a/src/test/test.json b/src/test/test.json new file mode 100644 index 0000000..7b6e91c --- /dev/null +++ b/src/test/test.json @@ -0,0 +1,2 @@ +{"test": "value", + "divIds": ["first", "second", "third"]} diff --git a/src/test/test.template b/src/test/test.template new file mode 100644 index 0000000..7feb761 --- /dev/null +++ b/src/test/test.template @@ -0,0 +1,9 @@ + + +

Test: ${test}

+ <% 3.times { idx -> %> +
+
+ <% } %> + +