Skip to content

Commit

Permalink
Merge pull request #1 from ECLK/master
Browse files Browse the repository at this point in the history
merge
  • Loading branch information
kosalag authored Jul 24, 2020
2 parents ca24bef + 069fc92 commit 048deca
Show file tree
Hide file tree
Showing 19 changed files with 8,533 additions and 7,517 deletions.
3 changes: 3 additions & 0 deletions distributor/src/distributor/constants.bal
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
const ERROR_REASON = "{eclk/pubhub}Error";

const ELECTION_TYPE_PRESIDENTIAL = "PRESIDENTIAL";
const ELECTION_TYPE_PARLIAMENTARY = "PARLIAMENTARY";
10 changes: 5 additions & 5 deletions distributor/src/distributor/genhtml.bal
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ function generateHtml (string electionCode, map<json> result, boolean sorted) re
foreach json j in partyResults {
map<json> pr = <map<json>> j; // value is a json object
if firstRound {
body += "<tr><td>" + <string>pr.candidate + "</td><td class='text-center'>" + <string>pr.party_code + "</td><td class='text-right'>" + commaFormatInt(<int>pr.votes) + "</td><td class='text-right'>" + <string>pr.percentage + "%</td></tr>";
body += "<tr><td>" + <string>pr.candidate + "</td><td class='text-center'>" + <string>pr.party_code + "</td><td class='text-right'>" + commaFormatInt(<int>pr.vote_count) + "</td><td class='text-right'>" + <string>pr.vote_percentage + "%</td></tr>";
} else {
body += "<tr><td>" + <string>pr.candidate + "</td><td class='text-center'>" + <string>pr.party_code
+ "</td><td class='text-right'>" + commaFormatInt(<int>pr.votes1st)
+ "</td><td class='text-right'>" + commaFormatInt(<int>pr.votes2nd)
+ "</td><td class='text-right'>" + commaFormatInt(<int>pr.votes3rd)
+ "</td><td class='text-right'>" + commaFormatInt(<int>pr.votes)
+ "</td><td class='text-right'>" + <string>pr.percentage + "%</td></tr>";
+ "</td><td class='text-right'>" + commaFormatInt(<int>pr.vote_count)
+ "</td><td class='text-right'>" + <string>pr.vote_percentage + "%</td></tr>";
}
}
body += "</table>";
Expand All @@ -90,8 +90,8 @@ function generateHtml (string electionCode, map<json> result, boolean sorted) re

function sortPartyResults (json[] unsorted) returns json[] {
return unsorted.sort(function (json r1, json r2) returns int {
int n1 = <int>r1.votes;
int n2 = <int>r2.votes;
int n1 = <int>r1.vote_count;
int n2 = <int>r2.vote_count;
return (n1 < n2) ? 1 : (n1 == n2 ? 0 : -1);
});
}
Expand Down
232 changes: 123 additions & 109 deletions distributor/src/distributor/messenger.bal
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
// import ballerina/config;
// import ballerina/log;
// import ballerina/stringutils;
// import wso2/twilio;
import ballerina/config;
import ballerina/log;
import ballerina/stringutils;
import chamil/govsms;

// twilio:TwilioConfiguration twilioConfig = {
// accountSId: config:getAsString("eclk.sms.twilio.accountSid"),
// authToken: config:getAsString("eclk.sms.twilio.authToken"),
// xAuthyKey: config:getAsString("eclk.sms.twilio.authyApiKey", "") // required only if Authy related APIs are used
// };
govsms:Configuration govsmsConfig = {
username: config:getAsString("eclk.govsms.username"),
password: config:getAsString("eclk.govsms.password")
};

// twilio:Client twilioClient = new(twilioConfig);
govsms:Client smsClient = new (govsmsConfig);

// // Keeps registered sms recipients in-memory. Values are populated in every service init and recipient registration
// map<string> mobileSubscribers = {};
// string sourceMobile = config:getAsString("eclk.sms.twilio.source");
// boolean validTwilioAccount = false;
// Keeps registered sms recipients in-memory. Values are populated in every service init and recipient registration
map<string> mobileSubscribers = {};
string sourceDepartment = config:getAsString("eclk.govsms.source");
boolean validSmsClient = false;

function getAwaitResultsMessage(string electionCode, string resultType, string resultCode, string level,
string? ed_name, string? pd_name) returns string {
Expand All @@ -24,8 +23,19 @@ function getAwaitResultsMessage(string electionCode, string resultType, string r
LEVEL_PD => {
string electoralDistrict = "/" + (ed_name ?: "<unknown electoral district>");
string pollingDivision = "/" + (pd_name ?: "<unknown polling division>");
message = "Await " + (resultCode.endsWith("P") ? "POSTAL" : "POLLING-DIVISION") + " results for "
+ electionCode + resultType + electoralDistrict + pollingDivision;

string pdLevelName = "";
if (resultCode.endsWith("PV")) {
pdLevelName = "POSTAL";
} else if (resultCode.endsWith("DV")) {
pdLevelName = "DISPLACED";
} else if (resultCode.endsWith("QV")) {
pdLevelName = "QUARANTINE";
} else {
pdLevelName = "POLLING-DIVISION";
}
message = "Await " + pdLevelName + " results for " + electionCode + resultType +
electoralDistrict + pollingDivision;
}
LEVEL_ED => {
string electoralDistrict = "/" + (ed_name ?: "<unknown electoral district>");
Expand All @@ -43,96 +53,100 @@ function getAwaitResultsMessage(string electionCode, string resultType, string r
return message + "(" + resultCode + ")";
}

// # Send SMS notification to all the subscribers.
// #
// # + message - The message to send
// # + resultId - The message identification
// function sendSMS(string message, string resultId) {
// map<string> currentMobileSubscribers = mobileSubscribers;
// if (currentMobileSubscribers.length() > 0) {
// log:printInfo("Sending SMS for " + resultId);
// }
// foreach string targetMobile in currentMobileSubscribers {
// log:printInfo("Sending SMS for " + resultId + " to " + targetMobile);
// var response = twilioClient->sendSms(sourceMobile, targetMobile, message);
// if response is error {
// log:printError("Message sending failed for \'" + targetMobile + "\' due to error:" +
// <string> response.detail()?.message);
// }
// }
// }

// # Validate and sanitize local mobile number into the proper format.(+94771234567).
// #
// # + mobileNo - User provided mobile number
// # + return - Formatted mobile number or the error
// function validate(string mobileNo) returns string|error {
// string mobile = <@untained> mobileNo.trim();

// boolean number = stringutils:matches(mobile, "^[0-9]*$");

// if !number {
// return error(ERROR_REASON, message = "Invalid mobile number. Given mobile number contains non numeric " +
// "characters: " + mobile);
// }

// if (mobile.startsWith("0") && mobile.length() == 10) {
// return "+94" + mobile.substring(1);
// }
// if (mobile.startsWith("94") && mobile.length() == 11) {
// return "+" + mobile;
// }
// // Allow only the local mobile numbers to register via public API. International number are avoided.
// return error(ERROR_REASON, message = "Invalid mobile number. Resend the request as follows: If the " +
// "mobile no is 0771234567, send POST request to \'/sms\' with JSON payload " +
// "\'{\"username\":\"myuser\", \"mobile\":\"0771234567\"}\'");
// }

// # Register recipient in the mobileSubscribers list and persist in the smsRecipients db table.
// #
// # + username - The recipient username
// # + mobileNo - The recipient number
// # + return - The status of registration or operation error
// function registerAsSMSRecipient(string username, string mobileNo) returns string|error {

// if mobileSubscribers.hasKey(username) {
// string errMsg = "Registration failed: username:" + username + " is already registered with mobile:" + mobileNo;
// log:printError(errMsg);
// return error(ERROR_REASON, message = errMsg);
// }

// // Persist recipient number in database
// var status = dbClient->update(INSERT_RECIPIENT, username, mobileNo);
// if status is error {
// log:printError("Failed to persist recipient no in database", status);
// return error(ERROR_REASON, message = "Registration failed: username:" + username + " mobile:" + mobileNo
// + ": " + <string> status.detail()?.message);
// }
// mobileSubscribers[username] = mobileNo;

// return "Successfully registered: username:" + username + " mobile:" + mobileNo;
// }

// # Unregister recipient from the mobileSubscribers map and remove from the smsRecipients db table.
// #
// # + username - The recipient username
// # + mobileNo - The recipient number
// # + return - The status of deregistration or operation error
// function unregisterAsSMSRecipient(string username, string mobileNo) returns string|error {

// // Remove persisted recipient number from database
// var status = dbClient->update(DELETE_RECIPIENT, username, mobileNo);
// if status is error {
// log:printError("Failed to remove recipient from the database", status);
// return error(ERROR_REASON, message = "Unregistration failed: username:" + username + " mobile:" + mobileNo +
// ": " + <string> status.detail()?.message);
// }

// if mobileSubscribers.hasKey(username) && mobileSubscribers.get(username) == mobileNo {
// return "Successfully unregistered: username:" + username + " mobile:" + mobileSubscribers.remove(username);
// }

// string errMsg = "Unregistration failed: No entry found for username:" + username + " mobile:" + mobileNo;
// log:printError(errMsg);
// return error(ERROR_REASON, message = errMsg);
// }
# Send SMS notification to all the subscribers.
#
# + message - The message to send
# + resultId - The message identification
function sendSMS(string message, string resultId) {
if (mobileSubscribers.length() == 0) {
return;
}
string logMessage = "Sending SMS for " + resultId;
log:printInfo(logMessage);
foreach string targetMobile in mobileSubscribers {
log:printInfo(logMessage + " to " + targetMobile);
var response = smsClient->sendSms(sourceDepartment, message, targetMobile);
if response is error {
log:printError("Message sending failed for \'" + targetMobile + "\'", response);
}
}
}

# Validate and sanitize local mobile number into the proper format.(0771234567).
#
# + mobileNo - User provided mobile number
# + return - Formatted mobile number or the error
function validate(string mobileNo) returns string|error {
string mobile = <@untained> mobileNo.trim();

if (mobile.startsWith("+94") && mobile.length() == 12) {
mobile = mobile.substring(1);
}

boolean number = stringutils:matches(mobile, "^[0-9]*$");
if !number {
return error(ERROR_REASON, message = "Invalid mobile number. Given mobile number contains non numeric " +
"characters: " + mobile);
}

if (mobile.startsWith("0") && mobile.length() == 10) {
return mobile;
}
if (mobile.startsWith("94") && mobile.length() == 11) {
return mobile;
}
// Allow only the local mobile numbers to register via public API. International number are avoided.
return error(ERROR_REASON, message = "Invalid mobile number. Resend the request as follows: If the " +
"mobile no is 0771234567, send POST request to \'/sms\' with JSON payload " +
"\'{\"username\":\"myuser\", \"mobile\":\"0771234567\"}\'");
}

# Register recipient in the mobileSubscribers list and persist in the smsRecipients db table.
#
# + username - The recipient username
# + mobileNo - The recipient number
# + return - The status of registration or operation error
function registerAsSMSRecipient(string username, string mobileNo) returns string|error {

if mobileSubscribers.hasKey(username) {
string errMsg = "Registration failed: username:" + username + " is already registered with mobile:" + mobileNo;
log:printError(errMsg);
return error(ERROR_REASON, message = errMsg);
}

// Persist recipient number in database
var status = dbClient->update(INSERT_RECIPIENT, username, mobileNo);
if status is error {
log:printError("Failed to persist recipient no in database", status);
return error(ERROR_REASON, message = "Registration failed: username:" + username + " mobile:" + mobileNo
+ ": " + <string> status.detail()?.message);
}
mobileSubscribers[username] = mobileNo;

return "Successfully registered: username:" + username + " mobile:" + mobileNo;
}

# Unregister recipient from the mobileSubscribers map and remove from the smsRecipients db table.
#
# + username - The recipient username
# + mobileNo - The recipient number
# + return - The status of deregistration or operation error
function unregisterAsSMSRecipient(string username, string mobileNo) returns string|error {
string result = "";
if mobileSubscribers.hasKey(username) && mobileSubscribers.get(username) == mobileNo {
result = "Successfully unregistered: username:" + username + " mobile:" + mobileSubscribers.remove(username);
} else {
string errMsg = "Unregistration failed: No entry found for username:" + username + " mobile:" + mobileNo;
log:printError(errMsg);
return error(ERROR_REASON, message = errMsg);
}

// Remove persisted recipient number from database
var status = dbClient->update(DELETE_RECIPIENT, username);
if status is error {
log:printError("Failed to remove recipient from the database", status);
return error(ERROR_REASON, message = "Failed to remove from the database: username:" + username + " mobile:"
+ mobileNo + ": " + <string> status.detail()?.message);
}
return result;
}
Loading

0 comments on commit 048deca

Please sign in to comment.