Permalink
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
grouper_training/ex401/data-generator.html
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
438 lines (362 sloc)
16.8 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script> | |
/* | |
TODO: | |
- Incorporate the courses (after adding more); | |
- randomly add a second non-duplticating affliate | |
*/ | |
// https://stackoverflow.com/a/424445 | |
function RNG(seed) { | |
// LCG using GCC's constants | |
this.m = 0x80000000; // 2**31; | |
this.a = 1103515245; | |
this.c = 12345; | |
this.state = seed ? seed : Math.floor(Math.random() * (this.m - 1)); | |
} | |
RNG.prototype.nextInt = function() { | |
this.state = (this.a * this.state + this.c) % this.m; | |
return this.state; | |
} | |
RNG.prototype.nextFloat = function() { | |
// returns in range [0,1] | |
return this.nextInt() / (this.m - 1); | |
} | |
RNG.prototype.nextRange = function(start, end) { | |
// returns in range [start, end): including start, excluding end | |
// can't modulu nextInt because of weak randomness in lower bits | |
var rangeSize = end - start; | |
var randomUnder1 = this.nextInt() / this.m; | |
return start + Math.floor(randomUnder1 * rangeSize); | |
} | |
RNG.prototype.choice = function(array) { | |
return array[this.nextRange(0, array.length)]; | |
} | |
var surnames = ["Gasper", "Smith", "Anderson", "Roberts", "Davis", "Brown", "Langenberg", "Vales", | |
"Grady", "Doe", "Morrison", "Walters", "Johnson", "Williams", "Peterson", "Martinez", "Thompson", | |
"White", "Lee", "Clark", "Lewis", "Lopez", "Gonazles", "Scott", "Henderson", "Butler", "Price", | |
"Nielson" | |
]; | |
var givenNames = ["John", "Michael", "Jennifer", "Nancy", "Bill", "William", | |
"Kiersten", "Marie", "Lori", "Mark", "Eric", "David", "Ann", | |
"Donna", "Paul", "Thomas", "Robert", "David", "Jim", "James", | |
"Blake", "Sarah", "Karoline", "Kim", "Erik", "Greg", "Karl", | |
"Colin", "Jo", "Betty", "Lisa", "Heather", "Mary", "Stephanie", "Christina", | |
"Christopher", "Jeremy", "Nancy", "Amber", "Adian", "Perry", "Steve", | |
"Andrew", "Megan", "Anna", "Claire", "Maddie", "Madison", "Debbie", "Lexi", | |
"Olivia", "Emma", "Ava", "Sophia", "Isabella", "Mia" | |
]; | |
var departments = ["Computer Science", "Engineering", "Business", "Accounting", | |
"Law", "Physical Education", "Language Arts", "Financial Aid", | |
"Information Technology", "Advising", "Purchasing", "Accounts Payable" | |
]; | |
var affiliations = ["student", "staff", "faculty", "alum", "community"]; | |
var courses = ["ACCT101", "ACCT201", "MATH100", "MATH101", "CS251", "CS252", | |
"ENGL101", "ENGL102", "ENGL201", "HIST101", "HIST102", | |
"SCI123", "SCI123", "SCI404" | |
]; | |
var rng; | |
function generateData() { | |
var people = []; | |
var seed = parseInt(document.getElementById('seed').value); | |
rng = new RNG(seed); | |
var personCount = parseInt(document.getElementById('count').value) - 1; | |
var peopleOu = document.getElementById('people_ou').value; | |
for (i = 0; i <= personCount; i++) { | |
surname = surnames[rng.nextRange(0, surnames.length)]; | |
givenName = givenNames[rng.nextRange(0, givenNames.length)]; | |
idNumber = "8" + (i + 1).toString().padStart(7, "0"); | |
uid = givenName[0] + surname + i; | |
var person = { | |
uid: uid.toLowerCase(), | |
surname: surname, | |
givenName: givenName, | |
idNumber: idNumber, | |
}; | |
people.push(person); | |
} | |
//Add additional randomized characteristics sets here; | |
//keep the ordering the same to maintain deterministic capabilities between runs | |
//Assign departments | |
for (index = 0; index < people.length; ++index) { | |
people[index]["department"] = departments[rng.nextRange(0, departments.length)]; | |
} | |
//Assign affiliations | |
for (index = 0; index < people.length; ++index) { | |
people[index]["affiliations"] = selectUnduplicated(affiliations, 2); | |
} | |
//Assign titles/primary affiliations | |
for (index = 0; index < people.length; ++index) { | |
people[index]["title"] = rankAffiliations(people[index].affiliations); | |
} | |
//Create Course Enrollments | |
for (index = 0; index < people.length; ++index) { | |
people[index]["courses"] = []; | |
if (people[index]["affiliations"].indexOf("student") > -1 | |
|| people[index]["affiliations"].indexOf("faculty") > -1) { | |
people[index]["courses"] = selectUnduplicated(courses, 4); | |
} | |
} | |
//Create vpn_users | |
for (index = 0; index < people.length; ++index) { | |
people[index].vpn_user = people[index].affiliations.indexOf('staff') >= 0 || people[index].affiliations.indexOf('faculty') >= 0 ? | |
(rng.nextFloat() > 0.1): //grab most faculty and staff | |
rng.nextFloat() > 0.9; // and only a few others | |
} | |
//Create vpn users ldap group | |
makeQuestionableVpnUsersLists(people); | |
//Create Athletics users | |
makeAthleticsUsersLists(people); | |
//Create lists of non-faculty (staff) banner users | |
makeNonFacultyBannerUsersLists(people); | |
//Create lists of visiting scholars | |
makeVisitingScholarsLists(people); | |
console.log(people); | |
//Generate Output | |
var ldif = ""; | |
for (j = 0; j < people.length; j++) { | |
ldif += formatPersonLdif(people[j], peopleOu); | |
} | |
ldif += formatVpnUsersGroupLdif(people, peopleOu); | |
ldif += formatCommunityGroupLdif(people, peopleOu); | |
document.getElementById('ldif').value = ldif; | |
var sql = ""; | |
sql += sqlHeader(); | |
for (k = 0; k < people.length; k++) { | |
sql += formatSqlSubjects(people[k]); | |
sql += formatSqlCourses(people[k]); | |
} | |
document.getElementById('sql').value = sql; | |
} | |
function formatPersonLdif(person, ou) { | |
var output = | |
"dn: uid=<uid>," + ou + "\n" + | |
"objectClass: organizationalPerson\n" + | |
"objectClass: person\n" + | |
"objectClass: top\n" + | |
"objectClass: inetOrgPerson\n" + | |
"objectClass: eduPerson\n" + | |
"surname: <surname>\n" + | |
"givenName: <givenName>\n" + | |
"cn: <givenName> <surname>\n" + | |
"uid: <uid>\n" + | |
"title: <title>\n" + | |
"employeeNumber: <idNumber>\n" + | |
"mail: <uid>@example.edu\n" + | |
"businessCategory:<department>\n" + | |
"userPassword: password\n"; | |
output = output.replace(/<uid>/g, person.uid); | |
output = output.replace(/<surname>/g, person.surname); | |
output = output.replace(/<givenName>/g, person.givenName); | |
output = output.replace(/<department>/g, person.department); | |
output = output.replace(/<title>/g, person.title); | |
output = output.replace(/<idNumber>/g, person.idNumber); | |
for (i = 0; i < person.affiliations.length; i++) { | |
output += "eduPersonAffiliation: " + person.affiliations[i] + "\n"; | |
} | |
return output + "\n"; | |
} | |
function formatVpnUsersGroupLdif(people, ou) { | |
var vpnOutput = | |
"dn: cn=vpn_users,ou=groups,dc=internet2,dc=edu\n" + | |
"objectClass: groupOfNames\n" + | |
"objectClass: top\n" + | |
"cn: vpn_users\n" | |
for (j = 0; j < people.length; j++) { | |
if (people[j].vpn_user == 1) { | |
vpnOutput = vpnOutput + "member: uid=" + people[j].uid + ',' + ou + "\n" | |
} | |
} | |
return vpnOutput + "\n"; | |
} | |
function formatCommunityGroupLdif(people, ou) { | |
var vpnOutput = | |
"dn: cn=community_members,ou=groups,dc=internet2,dc=edu\n" + | |
"objectClass: groupOfNames\n" + | |
"objectClass: top\n" + | |
"cn: community_members\n" | |
for (j = 0; j < people.length; j++) { | |
if (people[j].affiliations.indexOf('community') >= 0 ) { | |
vpnOutput = vpnOutput + "member: uid=" + people[j].uid + ',' + ou + "\n" | |
} | |
} | |
return vpnOutput + "\n"; | |
} | |
function sqlHeader() { | |
return "CREATE TABLE SIS_COURSES (\n" + | |
" termId varchar(255) NOT NULL,\n" + | |
" courseId varchar(255) NOT NULL,\n" + | |
" studentId varchar(255) NOT NULL,\n" + | |
" PRIMARY KEY (termId, courseId, studentId)\n" + | |
");\n\n" + | |
"CREATE TABLE HR_PEOPLE (\n" + | |
" id varchar(255) NOT NULL,\n" + | |
" surname varchar(255) default NULL,\n" + | |
" givenName varchar(255) default NULL,\n" + | |
" PRIMARY KEY (id)\n" + | |
");\n\n" + | |
"CREATE TABLE HR_PEOPLE_ROLES (\n" + | |
" id varchar(255) NOT NULL,\n" + | |
" role varchar(255) NOT NULL,\n" + | |
" PRIMARY KEY (id, role)\n" + | |
");\n\n"; | |
} | |
function formatSqlCourses(person) { | |
var template = | |
"INSERT INTO SIS_COURSES (termId, courseId, studentId) " + | |
"VALUES ('201810','<courseId>','<id>');\n"; | |
var output = ""; | |
for (i = 0; i < person.courses.length; i++) { | |
temp = template.replace(/<id>/g, person.idNumber); | |
temp = temp.replace(/<courseId>/g, person.courses[i]); | |
output += temp; | |
} | |
return output; | |
} | |
function formatSqlSubjects(person) { | |
var template = | |
"INSERT INTO HR_PEOPLE(id, surname, givenName) " + | |
"VALUES ('<id>','<surname>','<givenName>');\n"; | |
var output = ""; | |
temp = template.replace(/<id>/g, person.idNumber); | |
temp = temp.replace(/<surname>/g, person.surname); | |
temp = temp.replace(/<givenName>/g, person.givenName); | |
output += temp; | |
var template = | |
"INSERT INTO HR_PEOPLE_ROLES(id, role) " + | |
"VALUES ('<id>','<role>');\n"; | |
for (i = 0; i < person.affiliations.length; i++) { | |
var template = | |
"INSERT INTO HR_PEOPLE_ROLES(id, role) " + | |
"VALUES ('<id>','<role>');\n"; | |
if (person.affiliations[i] == 'staff' | |
|| person.affiliations[i] == 'faculty' | |
|| person.affiliations[i] =='student' | |
|| person.affiliations[i] =='community') { | |
temp = template.replace(/<id>/g, person.idNumber); | |
temp = temp.replace(/<role>/g, person.affiliations[i]); | |
output += temp; | |
} | |
} | |
return output; | |
} | |
function selectUnduplicated(source, max) { | |
var output = []; | |
count = rng.nextRange(0, max) + 1; | |
while (output.length < count) { | |
item = source[rng.nextRange(0, source.length)]; | |
if (output.indexOf(item) == -1) { | |
output.push(item); | |
} | |
} | |
return output; | |
} | |
function rankAffiliations(affiliations) { | |
if (affiliations.indexOf("faculty") > -1) | |
return "faculty"; | |
else if (affiliations.indexOf("staff") > -1) | |
return "staff"; | |
else if (affiliations.indexOf("student") > -1) | |
return "student"; | |
else if (affiliations.indexOf("alum") > -1) | |
return "alum"; | |
else | |
return "other"; | |
} | |
function makeQuestionableVpnUsersLists(people) { | |
var csvOutput = ""; | |
var gshOutput = 'addGroup("test", "cisoQuestionableVpnUsersList", "CISO VPN Questionable VPN List");\n'; | |
var sampleCount = 15; | |
for (i = 0; i < people.length && sampleCount > 0; i++) { | |
if (people[i].vpn_user == true & rng.nextFloat() > 0.75) { | |
csvOutput = csvOutput + people[i].uid + "\n"; | |
gshOutput = gshOutput + 'addMember("test:cisoQuestionableVpnUsersList","' + people[i].uid + '");\n'; | |
sampleCount--; | |
} | |
} | |
document.getElementById('vpnCsv').value = csvOutput; | |
document.getElementById('vpnGsh').value = gshOutput; | |
} | |
function makeAthleticsUsersLists(people) { | |
var csvOutput = ""; | |
var gshOutput = 'addGroup("app:mfa:ref", "athletics_dept", "athletics_dept");\n'; | |
var sampleCount = 15; | |
for (i = 0; i < people.length && sampleCount > 0; i++) { | |
if (people[i].affiliations.indexOf('staff') >= 0 & rng.nextFloat() > 0.75) { | |
csvOutput = csvOutput + people[i].uid + "\n"; | |
gshOutput = gshOutput + 'addMember("app:mfa:ref:athletics_dept","' + people[i].uid + '");\n'; | |
sampleCount--; | |
} | |
} | |
document.getElementById('athleticsCsv').value = csvOutput; | |
document.getElementById('athleticsGsh').value = gshOutput; | |
} | |
function makeNonFacultyBannerUsersLists(people) { | |
var csvOutput = ""; | |
var gshOutput = 'addGroup("app:mfa:ref", "NonFacultyBannerINB", "NonFacultyBannerINB");\n'; | |
var sampleCount = 35; | |
for (i = 100; i < people.length && sampleCount > 0; i++) { | |
if (people[i].affiliations.indexOf('staff') >= 0 & rng.nextFloat() > 0.75) { | |
csvOutput = csvOutput + people[i].uid + "\n"; | |
gshOutput = gshOutput + 'addMember("app:mfa:ref:NonFacultyBannerINB","' + people[i].uid + '");\n'; | |
sampleCount--; | |
} | |
} | |
document.getElementById('bannerCsv').value = csvOutput; | |
document.getElementById('bannerGsh').value = gshOutput; | |
} | |
function makeVisitingScholarsLists(people) { | |
var csvOutput = ""; | |
var gshOutput = 'addGroup("app:lms:ref", "visiting_scholars", "visiting_scholars");\n'; | |
var sampleCount = 25; | |
for (i = 300; i < people.length && sampleCount > 0; i++) { | |
if (people[i].affiliations.indexOf('community') >= 0) { | |
csvOutput = csvOutput + people[i].uid + "\n"; | |
gshOutput = gshOutput + 'addMember("app:lms:ref:visiting_scholars","' + people[i].uid + '");\n'; | |
sampleCount--; | |
} | |
} | |
document.getElementById('visitingScholarsCsv').value = csvOutput; | |
document.getElementById('visitingScholarsGsh').value = gshOutput; | |
} | |
</script> | |
</head> | |
<body> | |
<form> | |
Seed: <input type="text" name="seed" id="seed" value="6874" /> <br /> | |
Number of Subjects: <input type="text" name="count" id="count" value="1000" /> <br /> | |
People OU: <input type="text" name="people_ou" id="people_ou" value="ou=people,dc=internet2,dc=edu"/> <br /> | |
<input type="button" onclick="generateData(); return false;" value="Run" /> <br /> | |
</form> | |
<p> | |
Ldif: <br /><textarea cols="100" rows="15" id="ldif"></textarea><br /> | |
</p> | |
<p> | |
Sql: <br /><textarea cols="100" rows="15" id="sql"></textarea> <br /> | |
</p> | |
<p> | |
Questionable VPN Users CSV: <br /><textarea cols="100" rows="15" id="vpnCsv"></textarea> <br /> | |
</p> | |
<p> | |
Questionable VPN Users GSH: <br /><textarea cols="100" rows="15" id="vpnGsh"></textarea> <br /> | |
</p> | |
<p> | |
Athletic Dept CSV: <br /><textarea cols="100" rows="15" id="athleticsCsv"></textarea> <br /> | |
</p> | |
<p> | |
Atheltics Dept GSH: <br /><textarea cols="100" rows="15" id="athleticsGsh"></textarea> <br /> | |
</p> | |
<p> | |
Non-faculty Banner Users CSV: <br /><textarea cols="100" rows="15" id="bannerCsv"></textarea> <br /> | |
</p> | |
<p> | |
Non-faculty Banner Users GSH: <br /><textarea cols="100" rows="15" id="bannerGsh"></textarea> <br /> | |
</p> | |
<p> | |
Visiting Scholars Users CSV: <br /><textarea cols="100" rows="15" id="visitingScholarsCsv"></textarea> <br /> | |
</p> | |
<p> | |
Visiting Scholars Users GSH: <br /><textarea cols="100" rows="15" id="visitingScholarsGsh"></textarea> <br /> | |
</p> | |
</body> | |
</html> |