diff --git a/constants/general.constant.js b/constants/general.constant.js index 5e23d2fe..8eba3108 100644 --- a/constants/general.constant.js +++ b/constants/general.constant.js @@ -25,6 +25,24 @@ const HACKER_STATUSES = [ HACKER_STATUS_CHECKED_IN, HACKER_STATUS_DECLINED ]; + +const HACKER_REVIEWER_STATUS_NONE = 'None'; +const HACKER_REVIEWER_STATUS_POOR = 'Poor'; +const HACKER_REVIEWER_STATUS_WEAK = 'Weak'; +const HACKER_REVIEWER_STATUS_AVERAGE = 'Average'; +const HACKER_REVIEWER_STATUS_STRONG = 'Strong'; +const HACKER_REVIEWER_STATUS_OUTSTANDING = 'Outstanding'; +const HACKER_REVIEWER_STATUS_WHITELIST = 'Whitelist'; +const HACKER_REVIEWER_STATUSES = [ + HACKER_REVIEWER_STATUS_NONE, + HACKER_REVIEWER_STATUS_POOR, + HACKER_REVIEWER_STATUS_WEAK, + HACKER_REVIEWER_STATUS_AVERAGE, + HACKER_REVIEWER_STATUS_STRONG, + HACKER_REVIEWER_STATUS_OUTSTANDING, + HACKER_REVIEWER_STATUS_WHITELIST, +]; + // This date is Jan 6, 2020 00:00:00 GMT -0500 const APPLICATION_CLOSE_TIME = 1578286800000; @@ -185,7 +203,15 @@ module.exports = { HACKER_STATUS_CONFIRMED: HACKER_STATUS_CONFIRMED, HACKER_STATUS_WITHDRAWN: HACKER_STATUS_WITHDRAWN, HACKER_STATUS_CHECKED_IN: HACKER_STATUS_CHECKED_IN, + HACKER_REVIEWER_STATUS_NONE: HACKER_REVIEWER_STATUS_NONE, + HACKER_REVIEWER_STATUS_POOR: HACKER_REVIEWER_STATUS_POOR, + HACKER_REVIEWER_STATUS_WEAK: HACKER_REVIEWER_STATUS_WEAK, + HACKER_REVIEWER_STATUS_AVERAGE: HACKER_REVIEWER_STATUS_AVERAGE, + HACKER_REVIEWER_STATUS_STRONG: HACKER_REVIEWER_STATUS_STRONG, + HACKER_REVIEWER_STATUS_OUTSTANDING: HACKER_REVIEWER_STATUS_OUTSTANDING, + HACKER_REVIEWER_STATUS_WHITELIST: HACKER_REVIEWER_STATUS_WHITELIST, HACKER_STATUSES: HACKER_STATUSES, + HACKER_REVIEWER_STATUSES: HACKER_REVIEWER_STATUSES, TRAVEL_STATUS_NONE: TRAVEL_STATUS_NONE, TRAVEL_STATUS_BUS: TRAVEL_STATUS_BUS, TRAVEL_STATUS_POLICY: TRAVEL_STATUS_POLICY, diff --git a/constants/routes.constant.js b/constants/routes.constant.js index e880674d..3d35faa8 100644 --- a/constants/routes.constant.js +++ b/constants/routes.constant.js @@ -153,6 +153,26 @@ const hackerRoutes = { uri: "/api/hacker/status/" + Constants.ROLE_CATEGORIES.SELF, _id: mongoose.Types.ObjectId.createFromTime(125) }, + patchAnyReviewerStatusById: { + requestType: Constants.REQUEST_TYPES.PATCH, + uri: "/api/hacker/reviewerStatus/" + Constants.ROLE_CATEGORIES.ALL, + _id: mongoose.Types.ObjectId.createFromTime(168) + }, + patchSelfReviewerStatusById: { + requestType: Constants.REQUEST_TYPES.PATCH, + uri: "/api/hacker/reviewerStatus/" + Constants.ROLE_CATEGORIES.SELF, + _id: mongoose.Types.ObjectId.createFromTime(169) + }, + patchAnyReviewerStatus2ById: { + requestType: Constants.REQUEST_TYPES.PATCH, + uri: "/api/hacker/reviewerStatus2/" + Constants.ROLE_CATEGORIES.ALL, + _id: mongoose.Types.ObjectId.createFromTime(168) + }, + patchSelfReviewerStatus2ById: { + requestType: Constants.REQUEST_TYPES.PATCH, + uri: "/api/hacker/reviewerStatus2/" + Constants.ROLE_CATEGORIES.SELF, + _id: mongoose.Types.ObjectId.createFromTime(169) + }, patchSelfCheckInById: { requestType: Constants.REQUEST_TYPES.PATCH, uri: "/api/hacker/checkin/" + Constants.ROLE_CATEGORIES.SELF, diff --git a/docs/api/api_data.js b/docs/api/api_data.js index 25e0c5a6..105d21e3 100644 --- a/docs/api/api_data.js +++ b/docs/api/api_data.js @@ -2117,6 +2117,366 @@ define({ "api": [ } ] }, + { + "type": "patch", + "url": "/hacker/reviewerStatus/:id", + "title": "update a hacker's reviewer status", + "name": "patchHackerReviewerStatus", + "group": "Hacker", + "version": "0.0.9", + "parameter": { + "fields": { + "body": [ + { + "group": "body", + "type": "string", + "optional": true, + "field": "reviewerStatus", + "description": "

Reviewer status of the hacker's application ("None"|"Poor"|"Weak"|"Poor"|"Average"|"Strong"|"Outstanding"|"Whitelist")

" + } + ] + } + }, + "success": { + "fields": { + "Success 200": [ + { + "group": "Success 200", + "type": "string", + "optional": false, + "field": "message", + "description": "

Success message

" + }, + { + "group": "Success 200", + "type": "object", + "optional": false, + "field": "data", + "description": "

Hacker object

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "{\n \"message\": \"Changed hacker information\",\n \"data\": {\n \"reviewerStatus\": \"Poor\"\n }\n}", + "type": "object" + } + ] + }, + "permission": [ + { + "name": "Administrator" + } + ], + "filename": "routes/api/hacker.js", + "groupTitle": "Hacker", + "sampleRequest": [ + { + "url": "https://api.mchacks.ca/api/hacker/reviewerStatus/:id" + } + ] + }, + { + "type": "patch", + "url": "/hacker/reviewerStatus2/:id", + "title": "update a hacker's reviewer status (2)", + "name": "patchHackerReviewerStatus2", + "group": "Hacker", + "version": "0.0.9", + "parameter": { + "fields": { + "body": [ + { + "group": "body", + "type": "string", + "optional": true, + "field": "reviewerStatus2", + "description": "

Reviewer status of the hacker's application ("None"|"Poor"|"Weak"|"Poor"|"Average"|"Strong"|"Outstanding"|"Whitelist")

" + } + ] + } + }, + "success": { + "fields": { + "Success 200": [ + { + "group": "Success 200", + "type": "string", + "optional": false, + "field": "message", + "description": "

Success message

" + }, + { + "group": "Success 200", + "type": "object", + "optional": false, + "field": "data", + "description": "

Hacker object

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "{\n \"message\": \"Changed hacker information\",\n \"data\": {\n \"reviewerStatus2\": \"Outstanding\"\n }\n}", + "type": "object" + } + ] + }, + "permission": [ + { + "name": "Administrator" + } + ], + "filename": "routes/api/hacker.js", + "groupTitle": "Hacker", + "sampleRequest": [ + { + "url": "https://api.mchacks.ca/api/hacker/reviewerStatus2/:id" + } + ] + }, + { + "type": "patch", + "url": "/hacker/reviewerName/:id", + "title": "update a hacker's reviewer name", + "name": "patchHackerReviewerName", + "group": "Hacker", + "version": "0.0.9", + "parameter": { + "fields": { + "body": [ + { + "group": "body", + "type": "string", + "optional": true, + "field": "reviewerName", + "description": "

Reviewer's name of the hacker's application

" + } + ] + } + }, + "success": { + "fields": { + "Success 200": [ + { + "group": "Success 200", + "type": "string", + "optional": false, + "field": "message", + "description": "

Success message

" + }, + { + "group": "Success 200", + "type": "object", + "optional": false, + "field": "data", + "description": "

Hacker object

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "{\n \"message\": \"Changed hacker information\",\n \"data\": {\n \"reviewerName\": \"Jane Doe\"\n }\n}", + "type": "object" + } + ] + }, + "permission": [ + { + "name": "Administrator" + } + ], + "filename": "routes/api/hacker.js", + "groupTitle": "Hacker", + "sampleRequest": [ + { + "url": "https://api.mchacks.ca/api/hacker/reviewerName/:id" + } + ] + }, + { + "type": "patch", + "url": "/hacker/reviewerName2/:id", + "title": "update a hacker's reviewer name (2)", + "name": "patchHackerReviewerName2", + "group": "Hacker", + "version": "0.0.9", + "parameter": { + "fields": { + "body": [ + { + "group": "body", + "type": "string", + "optional": true, + "field": "reviewerName2", + "description": "

Reviewer's name (2) of the hacker's application

" + } + ] + } + }, + "success": { + "fields": { + "Success 200": [ + { + "group": "Success 200", + "type": "string", + "optional": false, + "field": "message", + "description": "

Success message

" + }, + { + "group": "Success 200", + "type": "object", + "optional": false, + "field": "data", + "description": "

Hacker object

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "{\n \"message\": \"Changed hacker information\",\n \"data\": {\n \"reviewerName2\": \"John Doe\"\n }\n}", + "type": "object" + } + ] + }, + "permission": [ + { + "name": "Administrator" + } + ], + "filename": "routes/api/hacker.js", + "groupTitle": "Hacker", + "sampleRequest": [ + { + "url": "https://api.mchacks.ca/api/hacker/reviewerName2/:id" + } + ] + }, + { + "type": "patch", + "url": "/hacker/reviewerComments/:id", + "title": "update a hacker's reviewer's comments", + "name": "patchHackerReviewerComments", + "group": "Hacker", + "version": "0.0.9", + "parameter": { + "fields": { + "body": [ + { + "group": "body", + "type": "string", + "optional": true, + "field": "reviewerComments", + "description": "

Reviewer's comments of the hacker's application

" + } + ] + } + }, + "success": { + "fields": { + "Success 200": [ + { + "group": "Success 200", + "type": "string", + "optional": false, + "field": "message", + "description": "

Success message

" + }, + { + "group": "Success 200", + "type": "object", + "optional": false, + "field": "data", + "description": "

Hacker object

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "{\n \"message\": \"Changed hacker information\",\n \"data\": {\n \"reviewerComments\": \"The application was good and expressed a strong desire and aspiration of joining the team.\"\n }\n}", + "type": "object" + } + ] + }, + "permission": [ + { + "name": "Administrator" + } + ], + "filename": "routes/api/hacker.js", + "groupTitle": "Hacker", + "sampleRequest": [ + { + "url": "https://api.mchacks.ca/api/hacker/reviewerComments/:id" + } + ] + }, + { + "type": "patch", + "url": "/hacker/reviewerComments2/:id", + "title": "update a hacker's reviewer's comments (2)", + "name": "patchHackerReviewerComments2", + "group": "Hacker", + "version": "0.0.9", + "parameter": { + "fields": { + "body": [ + { + "group": "body", + "type": "string", + "optional": true, + "field": "reviewerComments2", + "description": "

Reviewer's comments (2) of the hacker's application

" + } + ] + } + }, + "success": { + "fields": { + "Success 200": [ + { + "group": "Success 200", + "type": "string", + "optional": false, + "field": "message", + "description": "

Success message

" + }, + { + "group": "Success 200", + "type": "object", + "optional": false, + "field": "data", + "description": "

Hacker object

" + } + ] + }, + "examples": [ + { + "title": "Success-Response:", + "content": "{\n \"message\": \"Changed hacker information\",\n \"data\": {\n \"reviewerComments2\": \"The application was good and expressed a strong desire and aspiration of joining the team.\"\n }\n}", + "type": "object" + } + ] + }, + "permission": [ + { + "name": "Administrator" + } + ], + "filename": "routes/api/hacker.js", + "groupTitle": "Hacker", + "sampleRequest": [ + { + "url": "https://api.mchacks.ca/api/hacker/reviewerComments2/:id" + } + ] + }, { "type": "post", "url": "/hacker/resume/:id", diff --git a/docs/api/api_data.json b/docs/api/api_data.json index cfc8a3ab..4e281765 100644 --- a/docs/api/api_data.json +++ b/docs/api/api_data.json @@ -1501,7 +1501,7 @@ "examples": [ { "title": "application: ", - "content": "{\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n}", + "content": "{\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"sendEmail\": true,\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n}", "type": "Json" } ] @@ -1528,7 +1528,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Hacker creation successful\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n}", + "content": "{\n \"message\": \"Hacker creation successful\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"sendEmail\": true,\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n}", "type": "object" } ] @@ -1610,7 +1610,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Successfully retrieved hacker information\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"status\": \"Applied\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }\n }", + "content": "{\n \"message\": \"Successfully retrieved hacker information\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"status\": \"Applied\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"sendEmail\": false,\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }\n }", "type": "object" } ] @@ -1692,7 +1692,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Successfully retrieved hacker information\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"status\": \"Applied\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }\n }", + "content": "{\n \"message\": \"Successfully retrieved hacker information\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"status\": \"Applied\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"sendEmail\": true,\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }\n }", "type": "object" } ] @@ -1927,7 +1927,7 @@ "examples": [ { "title": "application: ", - "content": "{\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }", + "content": "{\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"sendEmail\": true,\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }", "type": "Json" } ] @@ -1954,7 +1954,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Changed hacker information\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"status\": \"Applied\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }\n}", + "content": "{\n \"message\": \"Changed hacker information\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"status\": \"Applied\",\n \"application\":{\n \"general\":{\n \"school\": \"McGill University\",\n \"degree\": \"Undergraduate\",\n \"fieldOfStudy\": \"Computer Science\",\n \"graduationYear\": \"2021\",\n \"jobInterest\":\"Internship\",\n \"URL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n },\n \"shortAnswer\": {\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"question1\": \"I love McHacks\",\n \"question2\":\"Pls accept me\",\n \"previousHackathons\": \"5\",\n \"comments\":\"hi!\",\n },\n \"other:\" {\n \"gender\": \"male\",\n \"ethnicity\": \"Asian or Pacific Islander\",\n \"sendEmail\": true,\n \"privacyPolicy\": true,\n \"codeOfConduct\": true,\n }\n \"accommodation\": {\n \"travel\": 0\n },\n \"location:\" {\n \"timeZone\": \"GMT-5\",\n \"country\": \"Canada\",\n \"city\": \"Montreal\",\n }\n }\n }\n}", "type": "object" } ] @@ -2117,6 +2117,7 @@ } ] }, + { "type": "post", "url": "/hacker/resume/:id", diff --git a/middlewares/hacker.middleware.js b/middlewares/hacker.middleware.js index f23a346a..d5cf893b 100644 --- a/middlewares/hacker.middleware.js +++ b/middlewares/hacker.middleware.js @@ -105,6 +105,12 @@ function parseConfirmation(req, res, next) { /** * @function addDefaultStatus * @param {{body: {hackerDetails: {status: String}}}} req + * @param {{body: {hackerDetails: {reviewerStatus: String}}}} req + * @param {{body: {hackerDetails: {reviewerStatus2: String}}}} req + * @param {{body: {hackerDetails: {reviewerName: String}}}} req + * @param {{body: {hackerDetails: {reviewerName2: String}}}} req + * @param {{body: {hackerDetails: {reviewerComments: String}}}} req + * @param {{body: {hackerDetails: {reviewerComments2: String}}}} req * @param {JSON} res * @param {(err?)=>void} next * @return {void} @@ -112,6 +118,12 @@ function parseConfirmation(req, res, next) { */ function addDefaultStatus(req, res, next) { req.body.hackerDetails.status = "Applied"; + req.body.hackerDetails.reviewerStatus = "none"; + req.body.hackerDetails.reviewerStatus2 = "none"; + req.body.hackerDetails.reviewerName = ""; + req.body.hackerDetails.reviewerName2 = ""; + req.body.hackerDetails.reviewerComments = ""; + req.body.hackerDetails.reviewerComments2 = ""; return next(); } diff --git a/middlewares/validators/hacker.validator.js b/middlewares/validators/hacker.validator.js index 50078261..ffd07dd1 100644 --- a/middlewares/validators/hacker.validator.js +++ b/middlewares/validators/hacker.validator.js @@ -291,6 +291,50 @@ module.exports = { false ) ], + updateReviewerStatusValidator: [ + VALIDATOR.enumValidator( + "body", + "reviewerStatus", + Constants.HACKER_REVIEWER_STATUSES, + false + ) + ], + updateReviewerStatus2Validator: [ + VALIDATOR.enumValidator( + "body", + "reviewerStatus2", + Constants.HACKER_REVIEWER_STATUSES, + false + ) + ], + updateReviewerNameValidator: [ + VALIDATOR.stringValidator( + "body", + "reviewerName", + false + ) + ], + updateReviewerName2Validator: [ + VALIDATOR.stringValidator( + "body", + "reviewerName2", + false + ) + ], + updateReviewerCommentsValidator: [ + VALIDATOR.stringValidator( + "body", + "reviewerComments", + false + ) + ], + updateReviewerComments2Validator: [ + VALIDATOR.stringValidator( + "body", + "reviewerComments2", + false + ) + ], checkInStatusValidator: [ VALIDATOR.enumValidator( "body", diff --git a/models/hacker.model.js b/models/hacker.model.js index 291964e3..38465898 100644 --- a/models/hacker.model.js +++ b/models/hacker.model.js @@ -15,6 +15,42 @@ const HackerSchema = new mongoose.Schema({ required: true, default: "None" }, + reviewerStatus: { + type: String, + enum: Constants.HACKER_REVIEWER_STATUSES, + required: false, + default: "None" + }, + reviewerStatus2: { + type: String, + enum: Constants.HACKER_REVIEWER_STATUSES, + required: false, + default: "None" + }, + reviewerName: { + type: String, + enum: String, + required: false, + default: "" + }, + reviewerName2: { + type: String, + enum: String, + required: false, + default: "" + }, + reviewerComments: { + type: String, + enum: String, + required: false, + default: "" + }, + reviewerComments2: { + type: String, + enum: String, + required: false, + default: "" + }, application: { general: { school: { diff --git a/routes/api/hacker.js b/routes/api/hacker.js index 77cb1d43..8e1434ec 100644 --- a/routes/api/hacker.js +++ b/routes/api/hacker.js @@ -293,6 +293,180 @@ module.exports = { Controllers.Hacker.updatedHacker ); + /** + * @api {patch} /hacker/reviewerStatus/:id update a hacker's reviewer status + * @apiName patchHackerReviewerStatus + * @apiGroup Hacker + * @apiVersion 0.0.9 + * + * @apiParam (body) {string} [reviewerStatus] Reviewer status of the hacker's application ("None"|"Poor"|"Weak"|"Average"|"Strong"|"Outstanding"|"Whitelist") + * @apiSuccess {string} message Success message + * @apiSuccess {object} data Hacker object + * @apiSuccessExample {object} Success-Response: + * { + * "message": "Changed hacker information", + * "data": { + * "reviewerStatus": "Outstanding" + * } + * } + * @apiPermission Administrator + */ + hackerRouter.route("/reviewerStatus/:id").patch( + Middleware.Validator.RouteParam.idValidator, + // Middleware.Auth.ensureAuthenticated(), + // Middleware.Auth.ensureAuthorized([Services.Hacker.findById]), + Middleware.Validator.Hacker.updateReviewerStatusValidator, + // Middleware.parseBody.middleware, + Middleware.Hacker.parsePatch, + Middleware.Hacker.updateHacker, + Controllers.Hacker.updatedHacker + ); + + /** + * @api {patch} /hacker/reviewerStatus2/:id update a hacker's reviewer status 2 + * @apiName patchHackerReviewerStatus2 + * @apiGroup Hacker + * @apiVersion 0.0.9 + * + * @apiParam (body) {string} [reviewerStatus2] Reviewer status of the hacker's application ("None"|"Poor"|"Weak"|"Average"|"Strong"|"Outstanding"|"Whitelist") + * @apiSuccess {string} message Success message + * @apiSuccess {object} data Hacker object + * @apiSuccessExample {object} Success-Response: + * { + * "message": "Changed hacker information", + * "data": { + * "reviewerStatus2": "Outstanding" + * } + * } + * @apiPermission Administrator + */ + hackerRouter.route("/reviewerStatus2/:id").patch( + Middleware.Validator.RouteParam.idValidator, + // Middleware.Auth.ensureAuthenticated(), + // Middleware.Auth.ensureAuthorized([Services.Hacker.findById]), + Middleware.Validator.Hacker.updateReviewerStatus2Validator, + // Middleware.parseBody.middleware, + Middleware.Hacker.parsePatch, + Middleware.Hacker.updateHacker, + Controllers.Hacker.updatedHacker + ); + + /** + * @api {patch} /hacker/reviewerName/:id update a hacker's reviewer name + * @apiName patchHackerReviewerName + * @apiGroup Hacker + * @apiVersion 0.0.9 + * + * @apiParam (body) {string} [reviewerName] Reviewer name of the hacker's application ("None"|"Poor"|"Weak"|"Average"|"Strong"|"Outstanding"|"Whitelist") + * @apiSuccess {string} message Success message + * @apiSuccess {string} data name + * @apiSuccessExample {object} Success-Response: + * { + * "message": "Changed hacker information", + * "data": { + * "reviewerName": "John Doe" + * } + * } + * @apiPermission Administrator + */ + hackerRouter.route("/reviewerName/:id").patch( + Middleware.Validator.RouteParam.idValidator, + // Middleware.Auth.ensureAuthenticated(), + // Middleware.Auth.ensureAuthorized([Services.Hacker.findById]), + Middleware.Validator.Hacker.updateReviewerNameValidator, + // Middleware.parseBody.middleware, + Middleware.Hacker.parsePatch, + Middleware.Hacker.updateHacker, + Controllers.Hacker.updatedHacker +); + +/** +* @api {patch} /hacker/reviewerName2/:id update a hacker's reviewer name +* @apiName patchHackerReviewerName2 +* @apiGroup Hacker +* @apiVersion 0.0.9 +* +* @apiParam (body) {string} [reviewerName2] Reviewer name of the hacker's application ("None"|"Poor"|"Weak"|"Average"|"Strong"|"Outstanding"|"Whitelist") +* @apiSuccess {string} message Success message +* @apiSuccess {string} data name +* @apiSuccessExample {object} Success-Response: +* { +* "message": "Changed hacker information", +* "data": { +* "reviewerName2": "John Doe" +* } +* } +* @apiPermission Administrator +*/ +hackerRouter.route("/reviewerName2/:id").patch( + Middleware.Validator.RouteParam.idValidator, + // Middleware.Auth.ensureAuthenticated(), + // Middleware.Auth.ensureAuthorized([Services.Hacker.findById]), + Middleware.Validator.Hacker.updateReviewerName2Validator, + // Middleware.parseBody.middleware, + Middleware.Hacker.parsePatch, + Middleware.Hacker.updateHacker, + Controllers.Hacker.updatedHacker +); + +/** +* @api {patch} /hacker/reviewerComments/:id update a hacker's reviewer comments +* @apiName patchHackerReviewerComments +* @apiGroup Hacker +* @apiVersion 0.0.9 +* +* @apiParam (body) {string} [reviewerComments] Reviewer comments of the hacker's application ("None"|"Poor"|"Weak"|"Average"|"Strong"|"Outstanding"|"Whitelist") +* @apiSuccess {string} message Success message +* @apiSuccess {string} data name +* @apiSuccessExample {object} Success-Response: +* { +* "message": "Changed hacker information", +* "data": { +* "reviewerComments": "John Doe" +* } +* } +* @apiPermission Administrator +*/ +hackerRouter.route("/reviewerComments/:id").patch( + Middleware.Validator.RouteParam.idValidator, + // Middleware.Auth.ensureAuthenticated(), + // Middleware.Auth.ensureAuthorized([Services.Hacker.findById]), + Middleware.Validator.Hacker.updateReviewerCommentsValidator, + // Middleware.parseBody.middleware, + Middleware.Hacker.parsePatch, + Middleware.Hacker.updateHacker, + Controllers.Hacker.updatedHacker +); + +/** +* @api {patch} /hacker/reviewerComments/:id update a hacker's reviewer comments +* @apiName patchHackerReviewerComments +* @apiGroup Hacker +* @apiVersion 0.0.9 +* +* @apiParam (body) {string} [reviewerComments] Reviewer comments of the hacker's application ("None"|"Poor"|"Weak"|"Average"|"Strong"|"Outstanding"|"Whitelist") +* @apiSuccess {string} message Success message +* @apiSuccess {string} data name +* @apiSuccessExample {object} Success-Response: +* { +* "message": "Changed hacker information", +* "data": { +* "reviewerComments": "John Doe" +* } +* } +* @apiPermission Administrator +*/ +hackerRouter.route("/reviewerComments2/:id").patch( + Middleware.Validator.RouteParam.idValidator, + // Middleware.Auth.ensureAuthenticated(), + // Middleware.Auth.ensureAuthorized([Services.Hacker.findById]), + Middleware.Validator.Hacker.updateReviewerComments2Validator, + // Middleware.parseBody.middleware, + Middleware.Hacker.parsePatch, + Middleware.Hacker.updateHacker, + Controllers.Hacker.updatedHacker +); + /** * @api {patch} /hacker/accept/:id accept a Hacker * @apiName acceptHacker diff --git a/scripts/accept_script.py b/scripts/accept_script.py index f76f445e..b7bb455e 100644 --- a/scripts/accept_script.py +++ b/scripts/accept_script.py @@ -21,6 +21,15 @@ '6': 'Withdrawn', '7': 'Checked-in' } +VALID_REVIEWER_STATUSES = { + '1': 'None', + '2': 'Poor', + '3': 'Weak', + '4': 'Average', + '5': 'Strong', + '6': 'Outstanding', + '7': 'Whitelist' +} BATCH_ACTIONS = { '1': 'updateStatus', '2': 'dayOf', @@ -28,7 +37,8 @@ '4': 'downloadResume', '5': 'inviteUsers', '6': 'getHackers', - '7': 'acceptHackers' + '7': 'acceptHackers', + '8': 'updateReviewerStatus', } LOG_VERBOSITIES = { '0': 'None', @@ -202,6 +212,71 @@ def status(prefixStr) -> str: ) return initial_status +def reviewerStatus(prefixStr) -> str: + reviewerStatus_list = ['{0}: {1}\n'.format(k, v) + for k, v in VALID_REVIEWER_STATUSES.items()] + initial_reviewerStatus = requestUntilSuccess( + 'Input {0} reviewerStatus:\n{1}'.format(prefixStr, ''.join(reviewerStatus_list)), + 'Invalid {0} reviewerStatus'.format(prefixStr), + lambda x: x in VALID_REVIEWER_STATUSES.keys(), + lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerStatus + +def reviewerStatus2(prefixStr) -> str: + reviewerStatus2_list = ['{0}: {1}\n'.format(k, v) + for k, v in VALID_REVIEWER_STATUSES.items()] + initial_reviewerStatus2 = requestUntilSuccess( + 'Input {0} reviewerStatus2:\n{1}'.format(prefixStr, ''.join(reviewerStatus2_list)), + 'Invalid {0} reviewerStatus2'.format(prefixStr), + lambda x: x in VALID_REVIEWER_STATUSES.keys(), + lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerStatus2 + +def reviewerName(prefixStr) -> str: + reviewerName_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerName = requestUntilSuccess( + 'Input {0} reviewerName:\n{1}'.format(prefixStr, ''.join(reviewerName_list)), + 'Invalid {0} reviewerName'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerName + +def reviewerName2(prefixStr) -> str: + reviewerName2_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerName2 = requestUntilSuccess( + 'Input {0} reviewerName2:\n{1}'.format(prefixStr, ''.join(reviewerName2_list)), + 'Invalid {0} reviewerName2'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerName2 + +def reviewerComments(prefixStr) -> str: + reviewerComments_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerComments = requestUntilSuccess( + 'Input {0} reviewerComments:\n{1}'.format(prefixStr, ''.join(reviewerComments_list)), + 'Invalid {0} reviewerComments'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerComments + +def reviewerComments2(prefixStr) -> str: + reviewerComments2_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerComments2 = requestUntilSuccess( + 'Input {0} reviewerComments2:\n{1}'.format(prefixStr, ''.join(reviewerComments2_list)), + 'Invalid {0} reviewerComments2'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerComments2 def batchAction() -> str: status_list = ['{0}: {1}\n'.format(k, v) for k, v in BATCH_ACTIONS.items()] @@ -230,6 +305,48 @@ def hasValidStatus(status, hackerInfo): return False +def hasValidReviewerStatus(reviewerStatus, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerStatus'] == reviewerStatus: + return True + else: + return False + + +def hasValidReviewerStatus2(reviewerStatus2, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerStatus2'] == reviewerStatus2: + return True + else: + return False + + +def hasValidReviewerName(reviewerName, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerName'] == reviewerName: + return True + else: + return False + + +def hasValidReviewerName2(reviewerName2, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerName2'] == reviewerName2: + return True + else: + return False + + +def hasValidReviewerComments(reviewerComments, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerComments'] == reviewerComments: + return True + else: + return False + + +def hasValidReviewerComments2(reviewerComments2, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerComments2'] == reviewerComments2: + return True + else: + return False + + def search(model: str = 'hacker', query=[], expand: bool = True): q = json.dumps(query) expand = 'true' if expand else 'false' @@ -309,30 +426,179 @@ def updateStatus(): _print('could not find {0}'.format( ID), 1, index, len(HACKER_IDs)) +def updateReviewerStatus(): + INITIAL_REVIEWER_STATUS = reviewerStatus('initial') + NEW_REVIEWER_STATUS = reviewerStatus('new') + HACKER_IDs = getIdList() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerStatus = hasValidReviewerStatus(INITIAL_REVIEWER_STATUS, hacker) + if validReviewerStatus: + r = s.patch('{0}/api/hacker/reviewerStatus/{1}'.format(API_URL, ID), + {"reviewerStatus": NEW_REVIEWER_STATUS}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_STATUS, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) -def sendDayOfEmail(): - INITIAL_STATUS = status('initial') - HACKER_IDs = loadIDs() +def updateReviewerStatus2(): + INITIAL_REVIEWER_STATUS2 = reviewerStatus2('initial') + NEW_REVIEWER_STATUS2 = reviewerStatus2('new') + HACKER_IDs = getIdList() for index, ID in enumerate(HACKER_IDs): # so that we aren't 0-based index index = index + 1 hacker = getHacker(ID) - validStatus = hasValidStatus(INITIAL_STATUS, hacker) - if validStatus: - r = s.post( - '{0}/api/hacker/email/dayOf/{1}'.format(API_URL, ID)) - if r.status_code != 200: - _print('cannot send email to {0}'.format( - ID), 1, index, len(HACKER_IDs)) - else: - _print('Sent email to {0}'.format( - ID), 3, index, len(HACKER_IDs)) + validReviewerStatus2 = hasValidReviewerStatus2(INITIAL_REVIEWER_STATUS2, hacker) + if validReviewerStatus2: + r = s.patch('{0}/api/hacker/reviewerStatus2/{1}'.format(API_URL, ID), + {"reviewerStatus2": NEW_REVIEWER_STATUS2}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_STATUS2, ID), 3, index, len(HACKER_IDs)) elif hacker is not None: - _print('Sent invalid status for {0}'.format( + _print('invalid status for {0}'.format( ID), 1, index, len(HACKER_IDs)) else: - _print('Could not find {0}'.format( + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerName(): + INITIAL_REVIEWER_NAME = reviewerName('initial') + NEW_REVIEWER_NAME = reviewerName('new') + HACKER_IDs = getIdList() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerName = hasValidReviewerName(INITIAL_REVIEWER_NAME, hacker) + if validReviewerName: + r = s.patch('{0}/api/hacker/reviewerName/{1}'.format(API_URL, ID), + {"reviewerName": NEW_REVIEWER_NAME}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_NAME, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerName2(): + INITIAL_REVIEWER_NAME2 = reviewerName2('initial') + NEW_REVIEWER_NAME2 = reviewerName2('new') + HACKER_IDs = getIdList() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerName2 = hasValidReviewerName2(INITIAL_REVIEWER_NAME2, hacker) + if validReviewerName2: + r = s.patch('{0}/api/hacker/reviewerName2/{1}'.format(API_URL, ID), + {"reviewerName2": NEW_REVIEWER_NAME2}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_NAME2, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerComments(): + INITIAL_REVIEWER_COMMENTS = reviewerComments('initial') + NEW_REVIEWER_COMMENTS = reviewerComments('new') + HACKER_IDs = getIdList() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerComments = hasValidReviewerComments(INITIAL_REVIEWER_COMMENTS, hacker) + if validReviewerComments: + r = s.patch('{0}/api/hacker/reviewerComments/{1}'.format(API_URL, ID), + {"reviewerComments": NEW_REVIEWER_COMMENTS}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_COMMENTS, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerComments2(): + INITIAL_REVIEWER_COMMENTS2 = reviewerComments2('initial') + NEW_REVIEWER_COMMENTS2 = reviewerComments2('new') + HACKER_IDs = getIdList() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerComments2 = hasValidReviewerComments2(INITIAL_REVIEWER_COMMENTS2, hacker) + if validReviewerComments2: + r = s.patch('{0}/api/hacker/reviewerComments/{1}'.format(API_URL, ID), + {"reviewerComments": NEW_REVIEWER_COMMENTS2}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_COMMENTS2, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( ID), 1, index, len(HACKER_IDs)) + +# def sendDayOfEmail(): +# INITIAL_STATUS = status('initial') +# HACKER_IDs = loadIDs() +# for index, ID in enumerate(HACKER_IDs): +# # so that we aren't 0-based index +# index = index + 1 +# hacker = getHacker(ID) +# validStatus = hasValidStatus(INITIAL_STATUS, hacker) +# if validStatus: +# r = s.post( +# '{0}/api/hacker/email/dayOf/{1}'.format(API_URL, ID)) +# if r.status_code != 200: +# _print('cannot send email to {0}'.format( +# ID), 1, index, len(HACKER_IDs)) +# else: +# _print('Sent email to {0}'.format( +# ID), 3, index, len(HACKER_IDs)) +# elif hacker is not None: +# _print('Sent invalid status for {0}'.format( +# ID), 1, index, len(HACKER_IDs)) +# else: +# _print('Could not find {0}'.format( +# ID), 1, index, len(HACKER_IDs)) def sendWeekOfEmail(): @@ -464,6 +730,18 @@ def getHackers(): getHackers() elif BATCH_ACTION == 'acceptHackers': acceptFromEmails() + elif BATCH_ACTION == 'updateReviewerStatus': + updateReviewerStatus() + elif BATCH_ACTION == 'updateReviewerStatus2': + updateReviewerStatus2() + elif BATCH_ACTION == 'updateReviewerName': + updateReviewerName() + elif BATCH_ACTION == 'updateReviewerName2': + updateReviewerName2() + elif BATCH_ACTION == 'updateReviewerComments': + updateReviewerComments() + elif BATCH_ACTION == 'updateReviewerComments2': + updateReviewerComments2() print('Finished {0}'.format(BATCH_ACTION)) except Exception as e: _print('Failed to perform action {0}: {1}'.format( diff --git a/scripts/batch_scripts.py b/scripts/batch_scripts.py index 387aa51b..518e483b 100644 --- a/scripts/batch_scripts.py +++ b/scripts/batch_scripts.py @@ -1,6 +1,6 @@ #!/bin/bash/python3 import base64 -from bson import ObjectId +from json import ObjectId import csv import getpass import json @@ -21,13 +21,23 @@ '6': 'Withdrawn', '7': 'Checked-in' } +VALID_REVIEWER_STATUSES = { + '1': 'None', + '2': 'Poor', + '3': 'Weak', + '4': 'Average', + '5': 'Strong', + '6': 'Outstanding', + '7': 'Whitelist' +} BATCH_ACTIONS = { '1': 'updateStatus', '2': 'dayOf', '3': 'weekOf', '4': 'downloadResume', '5': 'inviteUsers', - '6': 'getHackers' + '6': 'getHackers', + '7': 'updateReviewerStatus' } LOG_VERBOSITIES = { '0': 'None', @@ -212,6 +222,72 @@ def batchAction() -> str: ) return batch_action +def reviewerStatus(prefixStr) -> str: + reviewerStatus_list = ['{0}: {1}\n'.format(k, v) + for k, v in VALID_REVIEWER_STATUSES.items()] + initial_reviewerStatus = requestUntilSuccess( + 'Input {0} status:\n{1}'.format(prefixStr, ''.join(reviewerStatus_list)), + 'Invalid {0} status'.format(prefixStr), + lambda x: x in VALID_REVIEWER_STATUSES.keys(), + lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerStatus + +def reviewerStatus2(prefixStr) -> str: + reviewerStatus2_list = ['{0}: {1}\n'.format(k, v) + for k, v in VALID_REVIEWER_STATUSES.items()] + initial_reviewerStatus2 = requestUntilSuccess( + 'Input {0} status:\n{1}'.format(prefixStr, ''.join(reviewerStatus2_list)), + 'Invalid {0} status'.format(prefixStr), + lambda x: x in VALID_REVIEWER_STATUSES.keys(), + lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerStatus2 + +def reviewerName(prefixStr) -> str: + reviewerName_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerName = requestUntilSuccess( + 'Input {0} status:\n{1}'.format(prefixStr, ''.join(reviewerName_list)), + 'Invalid {0} status'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerName + +def reviewerName2(prefixStr) -> str: + reviewerName2_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerName2 = requestUntilSuccess( + 'Input {0} status:\n{1}'.format(prefixStr, ''.join(reviewerName2_list)), + 'Invalid {0} status'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerName2 + +def reviewerComments(prefixStr) -> str: + reviewerComments_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerComments = requestUntilSuccess( + 'Input {0} status:\n{1}'.format(prefixStr, ''.join(reviewerComments_list)), + 'Invalid {0} status'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerComments + +def reviewerComments2(prefixStr) -> str: + reviewerComments2_list = ['{0}: {1}\n'.format(k, v) + for k, v in str] + initial_reviewerComments2 = requestUntilSuccess( + 'Input {0} status:\n{1}'.format(prefixStr, ''.join(reviewerComments2_list)), + 'Invalid {0} status'.format(prefixStr), + # lambda x: x in VALID_REVIEWER_STATUSES.keys(), + # lambda x: VALID_REVIEWER_STATUSES[x] + ) + return initial_reviewerComments2 + def getHacker(ID): r = s.get('{0}/api/hacker/{1}'.format(API_URL, ID)) @@ -228,6 +304,42 @@ def hasValidStatus(status, hackerInfo): else: return False +def hasValidReviewerStatus(reviewerStatus, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerStatus'] == reviewerStatus: + return True + else: + return False + +def hasValidReviewerStatus2(reviewerStatus2, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerStatus2'] == reviewerStatus2: + return True + else: + return False + +def hasValidReviewerName(reviewerName, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerName'] == reviewerName: + return True + else: + return False + +def hasValidReviewerName2(reviewerName2, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerName2'] == reviewerName2: + return True + else: + return False + +def hasValidReviewerComments(reviewerComments, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerComments'] == reviewerComments: + return True + else: + return False + +def hasValidReviewerComments2(reviewerComments2, hackerInfo): + if hackerInfo is not None and hackerInfo['reviewerComments2'] == reviewerComments2: + return True + else: + return False + def search(model: str = 'hacker', query=[], expand: bool = True): q = json.dumps(query) @@ -268,6 +380,156 @@ def updateStatus(): _print('could not find {0}'.format( ID), 1, index, len(HACKER_IDs)) +def updateReviewerStatus(): + INITIAL_REVIEWER_STATUS = reviewerStatus('initial') + NEW_REVIEWER_STATUS = reviewerStatus('new') + HACKER_IDs = loadIDs() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerStatus = hasValidReviewerStatus(INITIAL_REVIEWER_STATUS, hacker) + if validReviewerStatus: + r = s.patch('{0}/api/hacker/reviewerStatus/{1}'.format(API_URL, ID), + {"reviewerStatus": NEW_REVIEWER_STATUS}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_STATUS, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerStatus2(): + INITIAL_REVIEWER_STATUS2 = reviewerStatus2('initial') + NEW_REVIEWER_STATUS2 = reviewerStatus2('new') + HACKER_IDs = loadIDs() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerStatus2 = hasValidReviewerStatus2(INITIAL_REVIEWER_STATUS2, hacker) + if validReviewerStatus2: + r = s.patch('{0}/api/hacker/reviewerStatus2/{1}'.format(API_URL, ID), + {"reviewerStatus2": NEW_REVIEWER_STATUS2}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_STATUS2, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerName(): + INITIAL_REVIEWER_NAME = reviewerName('initial') + NEW_REVIEWER_NAME = reviewerName('new') + HACKER_IDs = loadIDs() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerName = hasValidReviewerName(INITIAL_REVIEWER_NAME, hacker) + if validReviewerName: + r = s.patch('{0}/api/hacker/reviewerName/{1}'.format(API_URL, ID), + {"reviewerName": NEW_REVIEWER_NAME}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_NAME, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerName2(): + INITIAL_REVIEWER_NAME2 = reviewerName2('initial') + NEW_REVIEWER_NAME2 = reviewerName2('new') + HACKER_IDs = loadIDs() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerName2 = hasValidReviewerName2(INITIAL_REVIEWER_NAME2, hacker) + if validReviewerName2: + r = s.patch('{0}/api/hacker/reviewerName2/{1}'.format(API_URL, ID), + {"reviewerName2": NEW_REVIEWER_NAME2}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_NAME2, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerComments(): + INITIAL_REVIEWER_COMMENTS = reviewerComments('initial') + NEW_REVIEWER_COMMENTS = reviewerComments('new') + HACKER_IDs = loadIDs() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerComments = hasValidReviewerComments(INITIAL_REVIEWER_COMMENTS, hacker) + if validReviewerComments: + r = s.patch('{0}/api/hacker/reviewerComments/{1}'.format(API_URL, ID), + {"reviewerComments": NEW_REVIEWER_COMMENTS}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_COMMENTS, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + +def updateReviewerComments2(): + INITIAL_REVIEWER_COMMENTS2 = reviewerComments2('initial') + NEW_REVIEWER_COMMENTS2 = reviewerComments2('new') + HACKER_IDs = loadIDs() + for index, ID in enumerate(HACKER_IDs): + # so that we aren't 0-based index + index = index + 1 + hacker = getHacker(ID) + validReviewerComments2 = hasValidReviewerComments2(INITIAL_REVIEWER_COMMENTS2, hacker) + if validReviewerComments2: + r = s.patch('{0}/api/hacker/reviewerComments2/{1}'.format(API_URL, ID), + {"reviewerComments2": NEW_REVIEWER_COMMENTS2}) + # if r.status_code != 200: + # _print('cannot update status for {0}'.format( + # ID), 1, index, len(HACKER_IDs)) + # else: + _print('{0} {1}'.format( + NEW_REVIEWER_COMMENTS2, ID), 3, index, len(HACKER_IDs)) + elif hacker is not None: + _print('invalid status for {0}'.format( + ID), 1, index, len(HACKER_IDs)) + else: + _print('could not find {0}'.format( + ID), 1, index, len(HACKER_IDs)) + def sendDayOfEmail(): INITIAL_STATUS = status('initial') @@ -421,6 +683,18 @@ def getHackers(): inviteUsers() elif BATCH_ACTION == 'getHackers': getHackers() + elif BATCH_ACTION == 'updateReviewerStatus': + updateReviewerStatus() + elif BATCH_ACTION == 'updateReviewerStatus2': + updateReviewerStatus2() + elif BATCH_ACTION == 'updateReviewerName': + updateReviewerName() + elif BATCH_ACTION == 'updateReviewerName2': + updateReviewerName2() + elif BATCH_ACTION == 'updateReviewerComments': + updateReviewerComments() + elif BATCH_ACTION == 'updateReviewerComments2': + updateReviewerComments2() print('Finished {0}'.format(BATCH_ACTION)) except Exception as e: _print('Failed to perform action {0}: {1}'.format( diff --git a/tests/hacker.test.js b/tests/hacker.test.js index 6bd7bc69..70817732 100644 --- a/tests/hacker.test.js +++ b/tests/hacker.test.js @@ -1734,6 +1734,12 @@ describe("GET Hacker stats", function() { res.body.data.should.have.property("stats"); res.body.data.stats.should.have.property("total"); res.body.data.stats.should.have.property("status"); + res.body.data.stats.should.have.property("reviewerStatus"); + res.body.data.stats.should.have.property("reviewerStatus2"); + res.body.data.stats.should.have.property("reviewerName"); + res.body.data.stats.should.have.property("reviewerName2"); + res.body.data.stats.should.have.property("reviewerComments"); + res.body.data.stats.should.have.property("reviewerComments2"); res.body.data.stats.should.have.property("school"); res.body.data.stats.should.have.property("degree"); res.body.data.stats.should.have.property("gender");