diff --git a/Dockerfile.aws b/Dockerfile.aws index 03e9af4a..fcc9b809 100644 --- a/Dockerfile.aws +++ b/Dockerfile.aws @@ -1,5 +1,14 @@ -FROM golang:latest - +############################ +# STEP 1 build executable binary +############################ + +FROM golang:alpine AS builder + +# Install git. +# Git is required for fetching the dependencies. + +RUN apk update && apk add --no-cache git + ENV PATH=$PATH:/src/oef/ RUN mkdir -p /src/oef ADD . /src/oef @@ -8,7 +17,48 @@ COPY config/config.aws.yaml /src/oef/config/config.yaml WORKDIR /src/oef/ -RUN go build -o oef *.go +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o oef *.go +# RUN go build -o oef *.go + +############################ +# STEP 2 build a small image +############################ + +FROM scratch + +# Copy our static executable. +COPY --from=builder /src/oef/oef /src/oef/oef + +# Copy config file +COPY --from=builder /src/oef/config/config.yaml /src/oef/config/config.yaml + +# Copy templates +COPY --from=builder /src/oef/templates /src/oef/templates + +# Copy dist +COPY --from=builder /src/oef/dist /src/oef/dist + +# Copy VERSION file +COPY --from=builder /src/oef/VERSION /src/oef/VERSION + +WORKDIR /src/oef/ + +# Run the oef binary. ENTRYPOINT ["/src/oef/oef"] EXPOSE 80 + +# FROM golang:latest + +# ENV PATH=$PATH:/src/oef/ +# RUN mkdir -p /src/oef +# ADD . /src/oef + +# COPY config/config.aws.yaml /src/oef/config/config.yaml + +# WORKDIR /src/oef/ + +# RUN go build -o oef *.go +# ENTRYPOINT ["/src/oef/oef"] + +# EXPOSE 80 diff --git a/dist/main.bundle.js b/dist/main.bundle.js index de6f73de..9ec16244 100644 --- a/dist/main.bundle.js +++ b/dist/main.bundle.js @@ -73,8 +73,9 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__style_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__style_css__); -$(function () { +$(function () { + setInterval(function() { var timeleft = parseInt($("#timeleft").html()); if (timeleft > 0) { @@ -82,8 +83,20 @@ $(function () { } else { timeleft = 0; } - $("#timeleft").html(timeleft) + + $("#timeleft").html(timeleft); + + var minutes = Math.floor(timeleft/60); + var seconds = timeleft % 60; + + $("#timeleft_view").html(minutes+":"+seconds.toString().padStart(2, "0")); }, 1000); + + $("#reloadCaptcha").on("click",function(eventObject) { + image = eventObject.currentTarget; + + setSrcQuery(document.getElementById('image'), "reload=" + (new Date()).getTime()); + }); $("#myInput").on("keyup", function(eventObject) { @@ -132,6 +145,10 @@ $(function () { $(".karmen-ajax-delete").on("click", deleteHandler); + $("#reset_responses").on("click", function(eventObject) { + $('.form-check-input').removeAttr('checked'); + }); + }); @@ -143,4 +160,4 @@ $(function () { /***/ }) /******/ ]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZjVjMjdhYTFjNWFjNTQ0ZTIzNWIiLCJ3ZWJwYWNrOi8vLy4vc3JjL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NyYy9zdHlsZS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtRQUFBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBOzs7UUFHQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQSxLQUFLO1FBQ0w7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwyQkFBMkIsMEJBQTBCLEVBQUU7UUFDdkQsaUNBQWlDLGVBQWU7UUFDaEQ7UUFDQTtRQUNBOztRQUVBO1FBQ0Esc0RBQXNELCtEQUErRDs7UUFFckg7UUFDQTs7UUFFQTtRQUNBOzs7Ozs7OztBQzdEQTtBQUFBO0FBQUE7QUFBb0I7O0FBRXBCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFZLGVBQWU7QUFDM0IsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxnQkFBZ0IsbUJBQW1COztBQUVuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU4sRUFBRTs7QUFFRjtBQUNBOztBQUVBOztBQUVBLENBQUM7Ozs7Ozs7QUM3REQseUMiLCJmaWxlIjoibWFpbi5idW5kbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAwKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCBmNWMyN2FhMWM1YWM1NDRlMjM1YiIsImltcG9ydCAnLi9zdHlsZS5jc3MnXG5cbiQoZnVuY3Rpb24gKCkge1xuXG4gICAgc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7XG5cdHZhciB0aW1lbGVmdCA9IHBhcnNlSW50KCQoXCIjdGltZWxlZnRcIikuaHRtbCgpKTtcblx0aWYgKHRpbWVsZWZ0ID4gMCkge1xuXHQgICAgdGltZWxlZnQtLTtcblx0fSBlbHNlIHtcblx0ICAgIHRpbWVsZWZ0ID0gMDtcblx0fVxuXHQkKFwiI3RpbWVsZWZ0XCIpLmh0bWwodGltZWxlZnQpXG4gICAgfSwgMTAwMCk7XG4gICAgXG4gICAgJChcIiNteUlucHV0XCIpLm9uKFwia2V5dXBcIiwgZnVuY3Rpb24oZXZlbnRPYmplY3QpIHtcblx0XG5cdHZhciBpbnB1dCwgZmlsdGVyLCB1bCwgbGksIGEsIGk7XG5cblx0aW5wdXQgPSBldmVudE9iamVjdC5jdXJyZW50VGFyZ2V0O1xuXHRmaWx0ZXIgPSBpbnB1dC52YWx1ZS50b1VwcGVyQ2FzZSgpO1xuXHR1bCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibXlVTFwiKTtcblx0bGkgPSB1bC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnYScpO1xuXG5cdC8vIExvb3AgdGhyb3VnaCBhbGwgbGlzdCBpdGVtcywgYW5kIGhpZGUgdGhvc2Ugd2hvIGRvbid0IG1hdGNoIHRoZSBzZWFyY2ggcXVlcnlcblx0Zm9yIChpID0gMDsgaSA8IGxpLmxlbmd0aDsgaSsrKSB7XG5cdCAgICBhID0gbGlbaV07IC8vbGlbaV0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJhXCIpWzBdO1xuXHQgICAgaWYgKGEuaW5uZXJIVE1MLnRvVXBwZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID4gLTEpIHtcblx0XHRsaVtpXS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcblx0XHRsaVtpXS5jbGFzc0xpc3QuYWRkKFwib2VmLXNlbGVjdGVkLWJ5LXNlYXJjaFwiKTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0bGlbaV0uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXHRcdGxpW2ldLmNsYXNzTGlzdC5yZW1vdmUoXCJvZWYtc2VsZWN0ZWQtYnktc2VhcmNoXCIpO1xuXHQgICAgfVxuXHR9XG5cbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIGRlbGV0ZUhhbmRsZXIoZXZlbnRPYmplY3QpIHtcblx0dmFyIHVybCA9IHRoaXMuZGF0YXNldC51cmw7XG5cdHZhciBtb2RhbEVsID0gJCgnI2thcm1lbi1tb2RhbC1yZW1vdmUnKTtcblx0XG5cdHZhciBlbCA9ICQodGhpcyk7XG5cblx0bW9kYWxFbC5tb2RhbCh7YmFja2Ryb3A6ICdzdGF0aWMnfSkub25lKCdjbGljaycsICcja2FybWVuLW1vZGFsLWJ0bi1jb25maXJtJywgZnVuY3Rpb24oKSB7XG5cdCAgICBcblx0ICAgICQuYWpheCh7XG5cdFx0dXJsOiB1cmwsXG5cdFx0dHlwZTogJ0RFTEVURScsXG5cdFx0c3VjY2VzczogZnVuY3Rpb24ocmVzdWx0KSB7XG5cdFx0ICAgIG1vZGFsRWwubW9kYWwoJ2hpZGUnKTtcblx0XHQgICAgd2luZG93LmxvY2F0aW9uLnJlcGxhY2UocmVzdWx0LnJlZGlyZWN0X3VybCk7XG5cdFx0fVxuXHQgICAgfSk7XG5cdCAgICBcblx0fSk7XG5cdFxuXHRyZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICBcbiAgICAkKFwiLmthcm1lbi1hamF4LWRlbGV0ZVwiKS5vbihcImNsaWNrXCIsIGRlbGV0ZUhhbmRsZXIpO1xuXG59KTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHJlbW92ZWQgYnkgZXh0cmFjdC10ZXh0LXdlYnBhY2stcGx1Z2luXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvc3R5bGUuY3NzXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMjM0OWI1NDU2MjQ5MGEzYzg5ZGEiLCJ3ZWJwYWNrOi8vLy4vc3JjL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NyYy9zdHlsZS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtRQUFBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBOzs7UUFHQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQSxLQUFLO1FBQ0w7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwyQkFBMkIsMEJBQTBCLEVBQUU7UUFDdkQsaUNBQWlDLGVBQWU7UUFDaEQ7UUFDQTtRQUNBOztRQUVBO1FBQ0Esc0RBQXNELCtEQUErRDs7UUFFckg7UUFDQTs7UUFFQTtRQUNBOzs7Ozs7OztBQzdEQTtBQUFBO0FBQUE7QUFBb0I7OztBQUdwQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBWSxlQUFlO0FBQzNCLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsZ0JBQWdCLG1CQUFtQjs7QUFFbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNOztBQUVOLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTCxDQUFDOzs7Ozs7O0FDOUVELHlDIiwiZmlsZSI6Im1haW4uYnVuZGxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7XG4gXHRcdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbiBcdFx0XHRcdGdldDogZ2V0dGVyXG4gXHRcdFx0fSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgMjM0OWI1NDU2MjQ5MGEzYzg5ZGEiLCJpbXBvcnQgJy4vc3R5bGUuY3NzJ1xuXG5cbiQoZnVuY3Rpb24gKCkge1xuICAgIFxuICAgIHNldEludGVydmFsKGZ1bmN0aW9uKCkge1xuXHR2YXIgdGltZWxlZnQgPSBwYXJzZUludCgkKFwiI3RpbWVsZWZ0XCIpLmh0bWwoKSk7XG5cdGlmICh0aW1lbGVmdCA+IDApIHtcblx0ICAgIHRpbWVsZWZ0LS07XG5cdH0gZWxzZSB7XG5cdCAgICB0aW1lbGVmdCA9IDA7XG5cdH1cblxuXHQkKFwiI3RpbWVsZWZ0XCIpLmh0bWwodGltZWxlZnQpO1xuXHRcblx0dmFyIG1pbnV0ZXMgPSBNYXRoLmZsb29yKHRpbWVsZWZ0LzYwKTtcblx0dmFyIHNlY29uZHMgPSB0aW1lbGVmdCAlIDYwO1xuXHRcblx0JChcIiN0aW1lbGVmdF92aWV3XCIpLmh0bWwobWludXRlcytcIjpcIitzZWNvbmRzLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpKTtcbiAgICB9LCAxMDAwKTtcblxuICAgICQoXCIjcmVsb2FkQ2FwdGNoYVwiKS5vbihcImNsaWNrXCIsZnVuY3Rpb24oZXZlbnRPYmplY3QpIHtcblx0aW1hZ2UgPSBldmVudE9iamVjdC5jdXJyZW50VGFyZ2V0O1xuXHRcblx0c2V0U3JjUXVlcnkoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ltYWdlJyksIFwicmVsb2FkPVwiICsgKG5ldyBEYXRlKCkpLmdldFRpbWUoKSk7XG4gICAgfSk7XG4gICAgXG4gICAgJChcIiNteUlucHV0XCIpLm9uKFwia2V5dXBcIiwgZnVuY3Rpb24oZXZlbnRPYmplY3QpIHtcblx0XG5cdHZhciBpbnB1dCwgZmlsdGVyLCB1bCwgbGksIGEsIGk7XG5cblx0aW5wdXQgPSBldmVudE9iamVjdC5jdXJyZW50VGFyZ2V0O1xuXHRmaWx0ZXIgPSBpbnB1dC52YWx1ZS50b1VwcGVyQ2FzZSgpO1xuXHR1bCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibXlVTFwiKTtcblx0bGkgPSB1bC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnYScpO1xuXG5cdC8vIExvb3AgdGhyb3VnaCBhbGwgbGlzdCBpdGVtcywgYW5kIGhpZGUgdGhvc2Ugd2hvIGRvbid0IG1hdGNoIHRoZSBzZWFyY2ggcXVlcnlcblx0Zm9yIChpID0gMDsgaSA8IGxpLmxlbmd0aDsgaSsrKSB7XG5cdCAgICBhID0gbGlbaV07IC8vbGlbaV0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJhXCIpWzBdO1xuXHQgICAgaWYgKGEuaW5uZXJIVE1MLnRvVXBwZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID4gLTEpIHtcblx0XHRsaVtpXS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcblx0XHRsaVtpXS5jbGFzc0xpc3QuYWRkKFwib2VmLXNlbGVjdGVkLWJ5LXNlYXJjaFwiKTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0bGlbaV0uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXHRcdGxpW2ldLmNsYXNzTGlzdC5yZW1vdmUoXCJvZWYtc2VsZWN0ZWQtYnktc2VhcmNoXCIpO1xuXHQgICAgfVxuXHR9XG5cbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIGRlbGV0ZUhhbmRsZXIoZXZlbnRPYmplY3QpIHtcblx0dmFyIHVybCA9IHRoaXMuZGF0YXNldC51cmw7XG5cdHZhciBtb2RhbEVsID0gJCgnI2thcm1lbi1tb2RhbC1yZW1vdmUnKTtcblx0XG5cdHZhciBlbCA9ICQodGhpcyk7XG5cblx0bW9kYWxFbC5tb2RhbCh7YmFja2Ryb3A6ICdzdGF0aWMnfSkub25lKCdjbGljaycsICcja2FybWVuLW1vZGFsLWJ0bi1jb25maXJtJywgZnVuY3Rpb24oKSB7XG5cdCAgICBcblx0ICAgICQuYWpheCh7XG5cdFx0dXJsOiB1cmwsXG5cdFx0dHlwZTogJ0RFTEVURScsXG5cdFx0c3VjY2VzczogZnVuY3Rpb24ocmVzdWx0KSB7XG5cdFx0ICAgIG1vZGFsRWwubW9kYWwoJ2hpZGUnKTtcblx0XHQgICAgd2luZG93LmxvY2F0aW9uLnJlcGxhY2UocmVzdWx0LnJlZGlyZWN0X3VybCk7XG5cdFx0fVxuXHQgICAgfSk7XG5cdCAgICBcblx0fSk7XG5cdFxuXHRyZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICBcbiAgICAkKFwiLmthcm1lbi1hamF4LWRlbGV0ZVwiKS5vbihcImNsaWNrXCIsIGRlbGV0ZUhhbmRsZXIpO1xuXG4gICAgJChcIiNyZXNldF9yZXNwb25zZXNcIikub24oXCJjbGlja1wiLCBmdW5jdGlvbihldmVudE9iamVjdCkge1xuXHQkKCcuZm9ybS1jaGVjay1pbnB1dCcpLnJlbW92ZUF0dHIoJ2NoZWNrZWQnKTtcbiAgICB9KTtcbiAgICBcbn0pO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gcmVtb3ZlZCBieSBleHRyYWN0LXRleHQtd2VicGFjay1wbHVnaW5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9zdHlsZS5jc3Ncbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/docker/oef_aws/db.env b/docker/oef_aws/db.env new file mode 100644 index 00000000..807bd6f7 --- /dev/null +++ b/docker/oef_aws/db.env @@ -0,0 +1,10 @@ +MYSQL_ROOT_PASSWORD=oef +MYSQL_PASSWORD=oef +MYSQL_DATABASE=oef_prod +MYSQL_USER=oef + + + + + + diff --git a/docker/oef_aws/docker-compose.yml b/docker/oef_aws/docker-compose.yml new file mode 100644 index 00000000..2756416f --- /dev/null +++ b/docker/oef_aws/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.3" + +services: + + app: + image: andrea/oef:latest + ports: + - 80:80 + environment: + - DB_HOST=oef-micro.cjsemjfwbreb.eu-central-1.rds.amazonaws.com + - DB_PORT=3306 + + + diff --git a/docker/oef_regression_test/docker-compose.yaml b/docker/oef_regression_test/docker-compose.yaml index bacfe0ba..2c582262 100644 --- a/docker/oef_regression_test/docker-compose.yaml +++ b/docker/oef_regression_test/docker-compose.yaml @@ -42,6 +42,7 @@ services: - "4444:4444" - "5900:5900" volumes: + - /etc/localtime:/etc/localtime:ro - /dev/shm:/dev/shm volumes: diff --git a/orm/response.go b/orm/response.go index 37084911..3325d824 100644 --- a/orm/response.go +++ b/orm/response.go @@ -240,14 +240,25 @@ func (model *Response) Update(db *Database, args map[string]string, w http.Respo } // Check if the contest is still active - if !response.(*Response).IsActive() { + if isParticipant(r) && !response.(*Response).IsActive() { return nil, errors.OutOfTime } + + response.(*Response).SingleResponses = make([]*SingleResponse, 0) + err = renderer.Decode(response, r) if err != nil { return nil, err } + // If there aren't single responses then participant + // response Starttime is resetted. + if isAdministrator(r) { + if len(response.(*Response).SingleResponses) == 0 { + response.(*Response).StartTime = time.Time{} + } + } + WriteUpdater(r, response.(*Response)) _, err = SaveResponse(db, response) diff --git a/regression_test/regression_test.go b/regression_test/regression_test.go index 2d4ae25e..581856ef 100644 --- a/regression_test/regression_test.go +++ b/regression_test/regression_test.go @@ -231,6 +231,106 @@ func (t *testSuite) TestSchoolSubscription() { } +func (t *testSuite) TestParticipantResponse() { + login("WINBOXGUF", "GUf3wIP0DF7") + + err := findElement("a.btn-primary").Click() + if err != nil { + panic(err) + } + + err = findElement("#update-response").Click() + if err != nil { + panic(err) + } + + correct := []string{ + "97", "129", "105", "113", "93", "89", "109", "141", "157", + "85", "133", "153", "121", "117", "101", "149", "81", "145", + "125", "137", + } + + for _, answerId := range correct { + err = findElement("#answer_" + answerId).Click() + if err != nil { + panic(err) + } + } + + err = findElement("button.btn-primary").Click() + if err != nil { + panic(err) + } + + logout() + + login("admin", "admin") + + err = findElement("#responses_navbar_link").Click() + if err != nil { + panic(err) + } + + err = findElement("#myInput").SendKeys("BOXILL") + if err != nil { + panic(err) + } + err = findElement("a.oef-selected-by-search").Click() + if err != nil { + panic(err) + } + + scoreEl := findElement("#score") + score, err := scoreEl.Text() + + t.Nil(err) + t.Equal("20", score) + + err = findElement("a.btn-primary").Click() + if err != nil { + panic(err) + } + + err = findElement("#reset_responses").Click() + if err != nil { + panic(err) + } + + err = findElement("button.btn-primary").Click() + if err != nil { + panic(err) + } + + logout() +} + +func (t *testSuite) TestContestActiveWindow() { + login("admin", "admin") + + err := searchAndClick("junior") + if err != nil { + panic(err) + } + + err = findElement("a.btn-primary").Click() + if err != nil { + panic(err) + } + + err = findElement("#contest_description").SendKeys("Gara per la categoria JUNIOR") + + err = findElement("#contest_date").SendKeys("2020-03-04") + err = findElement("#contest_start_time").SendKeys("14:00") + err = findElement("#contest_end_time").SendKeys("15:00") + err = findElement("#contest_duration").SendKeys("45") + + err = findElement(".btn-primary").Click() + + t.True(true) + + logout() +} + func findElement(selector string) selenium.WebElement { element, err := wd.FindElement(selenium.ByCSSSelector, selector) if err != nil { @@ -436,3 +536,16 @@ func clickPrimaryButton() { panic(err) } } + +func searchAndClick(text string) error { + err := findElement("#myInput").SendKeys(text) + if err != nil { + return err + } + err = findElement("a.oef-selected-by-search").Click() + if err != nil { + return err + } + + return nil +} diff --git a/scripts/export_schools/.gitignore b/scripts/export_schools/.gitignore new file mode 100644 index 00000000..afed0735 --- /dev/null +++ b/scripts/export_schools/.gitignore @@ -0,0 +1 @@ +*.csv diff --git a/scripts/export_schools/export_schools b/scripts/export_schools/export_schools new file mode 100755 index 00000000..1fb1b1e4 Binary files /dev/null and b/scripts/export_schools/export_schools differ diff --git a/scripts/export_schools/main.go b/scripts/export_schools/main.go new file mode 100644 index 00000000..8bac1b96 --- /dev/null +++ b/scripts/export_schools/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "flag" + "os" + + "git.andreafazzi.eu/andrea/oef/client" + "git.andreafazzi.eu/andrea/oef/orm" + "github.com/gocarina/gocsv" +) + +func main() { + username := flag.String("username", "admin", "Username") + password := flag.String("password", "admin", "Password") + output := flag.String("output", "schools.csv", "Output filename") + + flag.Parse() + + client, err := client.Dial(flag.Arg(0), *username, *password) + if err != nil { + panic(err) + } + schools := make([]*orm.School, 0) + err = client.ReadAll(&schools) + if err != nil { + panic(err) + } + + f, err := os.Create(*output) + if err != nil { + panic(err) + } + defer f.Close() + + gocsv.MarshalFile(schools, f) +} diff --git a/scripts/export_schools/scuole.xlsx b/scripts/export_schools/scuole.xlsx new file mode 100644 index 00000000..6cbbccc2 Binary files /dev/null and b/scripts/export_schools/scuole.xlsx differ diff --git a/src/index.js b/src/index.js index af767544..d42ec050 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import './style.css' $(function () { - + setInterval(function() { var timeleft = parseInt($("#timeleft").html()); if (timeleft > 0) { @@ -10,7 +10,13 @@ $(function () { } else { timeleft = 0; } - $("#timeleft").html(timeleft) + + $("#timeleft").html(timeleft); + + var minutes = Math.floor(timeleft/60); + var seconds = timeleft % 60; + + $("#timeleft_view").html(minutes+":"+seconds.toString().padStart(2, "0")); }, 1000); $("#reloadCaptcha").on("click",function(eventObject) { @@ -66,4 +72,8 @@ $(function () { $(".karmen-ajax-delete").on("click", deleteHandler); + $("#reset_responses").on("click", function(eventObject) { + $('.form-check-input').removeAttr('checked'); + }); + }); diff --git a/templates/layout/base.html.tpl b/templates/layout/base.html.tpl index caaaf78a..2b728375 100644 --- a/templates/layout/base.html.tpl +++ b/templates/layout/base.html.tpl @@ -45,7 +45,7 @@ Risposte Scuole Partecipanti - Prove + Prove {{- end -}} {{- if $isSchool -}} Scuola diff --git a/templates/layout/login.html.tpl b/templates/layout/login.html.tpl index 4238442f..abb81010 100644 --- a/templates/layout/login.html.tpl +++ b/templates/layout/login.html.tpl @@ -37,7 +37,7 @@ diff --git a/templates/responses_add_update.html.tpl b/templates/responses_add_update.html.tpl index cadd463d..39c3fd84 100644 --- a/templates/responses_add_update.html.tpl +++ b/templates/responses_add_update.html.tpl @@ -46,7 +46,7 @@ {{if isResponseIn $answer.ID $.Data.AnswersIDs}} {{$checked = true}} {{end}} - + @@ -71,10 +71,12 @@
Gara
{{.Data.Contest}}
Partecipante
{{.Data.Participant}}
{{- if $isParticipant -}} -
Tempo rimanente
{{if .Data.TimeLeft}}
{{.Data.TimeLeft.Seconds|toInt}} secondi rimanenti
{{else}}
La gara è sempre attiva
{{end}} + +
Tempo rimanente
{{if .Data.TimeLeft}}
minuti rimanenti
{{else}}
La gara è sempre attiva
{{end}} {{- end -}} + {{if $isAdmin}}{{end}} diff --git a/templates/responses_show.html.tpl b/templates/responses_show.html.tpl index 87cb6f2b..312a6ea2 100644 --- a/templates/responses_show.html.tpl +++ b/templates/responses_show.html.tpl @@ -48,7 +48,7 @@
nessuna risposta fornita
{{end}}
Punteggio
-
{{.Data.Score}}
+
{{.Data.Score}}
{{if $creatorUser:=.Data.CreatedBy}}
Creato da
{{$creatorUser.Username}}[{{$creatorUser.Role}}] {{$.Data.CreatedAt|prettyDateTime}} da {{.Data.CreatorIP}}
@@ -76,7 +76,7 @@ {{if .Data.IsActive}}

Per iniziare o riprendere la gara clicca sul pulsante a destra. - + Vai alla gara!