Skip to content

Instantly share code, notes, and snippets.

@gabonator
Last active May 18, 2017 12:10
Show Gist options
  • Save gabonator/76dae36899375eb23ed6ff34c883a294 to your computer and use it in GitHub Desktop.
Save gabonator/76dae36899375eb23ed6ff34c883a294 to your computer and use it in GitHub Desktop.
Aktion.Next dochadzovky system
'option strict';
module.exports.getAttendance = function(user, pass, date, handler)
{
console.log("Get attendance name&pwd: "+user);
getSession(user, pass,
function(result)
{
if ( !result )
{
handler();
return;
}
getAttendance(date, result, handler);
})
}
module.exports.getAttendanceByName = function(user, date, handler)
{
console.log("Get attendance by name: "+user);
fs.readFile('users/'+user+'.idr', 'ascii', function (err, idr)
{
if (err)
{
handler();
return;
}
fs.readFile('users/'+user+'.cookie', 'ascii', function (err, cookie)
{
if (err)
{
handler();
return;
}
getAttendance(date, [cookie, idr], handler);
})
});
}
module.exports.getSession = function(user, pass, handler)
{
getSession(user, pass, handler);
}
module.exports.getAttendanceBySession = function(date, session, handler)
{
getAttendance(date, session, handler)
}
module.exports.refreshCookies = function()
{
return; // TODO: not working
fs.readdirSync("users").forEach(file => {
if ( file.substr(-7) == ".cookie")
{
var user = file.replace(".cookie", "");
fs.readFile('users/'+user+'.idr', 'ascii', function (err, idr)
{
if (!err)
fs.readFile('users/'+user+'.cookie', 'ascii', function (err, cookie)
{
if (!err)
{
refreshSession(cookie, idr, function(nidr)
{
console.log("Refreshing "+user+" : "+idr + " = "+nidr);
});
}
})
});
}
})
}
var request = require("request");
var fs = require("fs");
function refreshSession(cookies, idr, handler)
{
handler();
}
function addCookie(cookies)
{
var str = "";
for (var i in cookies)
str += cookies[i].substr(0, cookies[i].indexOf(';')) + ";";
return str;
}
function getSession(user, pass, handler)
{
var options = {
url: 'https://xyz.xyz.com/AktionNEXT/Login.aspx',
headers: {
'Origin':'https://xyz.xyz.com' ,
'Content-Type':'application/x-www-form-urlencoded',
'Cookie':''
},
body:
'__VIEWSTATE=lV2u045y5tbjRyKV9MS2%2FnGTJ3ju%2..........&'+
'ctl00%24phContent%24pnlLogin%24txtLogin='+user+'&'+
'ctl00%24phContent%24pnlLogin%24txtPassword='+pass+'&'+
'cmbDomain_VI=.....&'+
'ctl00%24phContent%24pnlLogin%24cmbDomain=.....&'+
'ctl00%24phContent%24pnlLogin%24cmbDomain%24DDD=%7B%26quot%3BwindowsState%26quot%3B%3A%26quot%3B0%3A0%3A12000%3A471%3A418%3A1%3A238%3A48%3A1%3A0%3A0%3A0%26quot%3B%7D&'+
'ctl00%24phContent%24pnlLogin%24cmbDomain%24DDD%24L%24State=%7B%26quot%3BCustomCallback%26quot%3B%3A%26quot%3B%26quot%3B%7D&'+
'ctl00%24phContent%24pnlLogin%24cmbDomain%24DDD%24L=.....&'+
'ctl00%24phContent%24pnlLogin%24btnLogin=Log+in&'
};
function callback(error, response, body)
{
if (error || response.statusCode!=302)
{
handler();
return;
}
// options.url = "https://xyz.xyz.com" + response.headers.location;
options.url = "https://xyz.xyz.com/AktionNEXT/UrlTo.aspx?loc=AttMyAttendance";
options.headers["Cookie"] += addCookie( response.headers["set-cookie"] );
options = {url:options.url, headers:options.headers};
request(options, function(error, response, body)
{
// options.headers["Cookie"] += addCookie( response.headers["set-cookie"] );
var idr = body.match("idr=(.{36})");
if (!idr || idr.length < 2)
handler()
else
{
storeSession(user, options.headers["Cookie"], idr[1]);
handler([options.headers["Cookie"], idr[1]]);
}
});
}
request.post(options, callback);
}
function getAttendance(month, session, handler)
{
session[0].replace('ACulture=sk-sk', 'ACulture=en-us');
var options = {
url:'https://xyz.xyz.com/AktionNEXT/agenda.aspx?ida=60&dt='+month+'&dtt=0&awp=Pruchody&idr=' + session[1],
headers: {
'Content-Type':'application/x-www-form-urlencoded',
'Cookie':session[0] + 'ACulture=en-us; ',
},
body:
'__EVENTTARGET=ctl00%24phContent%24ctl00%24menuGrid&'+
'__EVENTARGUMENT=CLICK%3A5i4&'+
'__VIEWSTATE=LWU2tmFySoQ41y%2Fzz8v2RS........&'+
'ctl00%24phContent%24ctl00%24hdnGridMenu=%7B%26quot%3Bdata%26quot%3B%3A%26quot%3B12%7C%23%7CEXPORTMODE%7C4%7C4%7C1ALL%23%26quot%3B%7D'
}
request.post(options, function(error, response, body)
{
if (response.statusCode != 200 || !body)
handler();
else
handler(body.split("\r\n"));
});
}
function storeSession(user, cookie, idr)
{
fs.writeFile("users/"+user+".idr", idr, function () {});
fs.writeFile("users/"+user+".cookie", cookie, function () {});
}
<body>
login: <input type="text" id="login" value="" size=8>
password: <input type="password" id="password" size=8>
date: <input type="text" id="date" value="" size=8>
<input type="button" value="Get attendance" onClick="get()">
<br><br>
<div id="out"></div>
</body>
<script>
date.value = new Date().getFullYear() + "" + ("0"+(new Date().getMonth()+1)).substr(-2) + "01";
if (window.location.hash != "")
{
login.value = window.location.hash.substr(1);
password.value = "";
get();
}
function get()
{
download("?getAttendance('"+login.value+"', '"+password.value+"', '"+date.value+"')", function(resp)
{
if (!resp)
{
showError();
return;
}
window.location.hash = login.value;
resp = resp.split("\n");
var data = [];
var lastdate = "";
for (var i in resp)
{
var tokens = resp[i].indexOf(',') != -1 ? resp[i].split(",") : resp[i].split(";");
if (!tokens || tokens.length != 11)
continue;
var curdate = tokens[1];
if ( curdate != lastdate )
{
data.push({day:tokens[1].substr(4, 2), month:tokens[1].substr(7, 2), events:[]});
lastdate = curdate;
}
data[data.length-1].events.push({day:tokens[1], hour:tokens[2].substr(0, 2), minute:tokens[2].substr(3, 2), event:tokens[3][0], extra:''});
}
visualize(data);
});
}
function showError()
{
out.innerHTML = "Neuspesne prihlasenie";
}
function visualize(data)
{
out.innerHTML = visual(data);
}
function download(url, handler)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200)
handler(this.responseText);
else
handler();
};
xhttp.open("GET", url, true);
xhttp.send();
}
</script>
<script src="visualize.js"></script>
"use strict";
var request = require("request");
var http = require('http');
var url = require('url');
var fs = require('fs');
var webbase = ".";
var attendanceApi = require('./attendance.js');
var port = 8888;
setInterval(function()
{
attendanceApi.refreshCookies();
}, 10*60*1000);
http.createServer(function (request, response) {
if (typeof(request.headers.origin) != "undefined")
{
// CORS
response.setHeader('Access-Control-Allow-Origin', request.headers.origin);
response.setHeader('Access-Control-Request-Method', 'GET');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', 'authorization, content-type');
}
if ( request.method === 'OPTIONS' )
{
response.writeHead(200);
response.end();
return;
}
var parsedUrl = url.parse(request.url);
var uri = parsedUrl.pathname;
var query = parsedUrl.query;
if ( !query )
{
if ( uri == "/" )
uri = "/index.html";
var file = webbase + uri;
fs.exists( file, function(exists)
{
if(!exists)
{
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
return;
}
if ( file.substr(-5) == ".html" )
response.writeHead(200, {'Content-Type': 'text/html'});
else if ( file.substr(-4) == ".css" )
response.writeHead(200, {'Content-Type': 'text/css'});
else if ( file.substr(-4) == ".ico" )
response.writeHead(200, {'Content-Type': 'image/x-icon'});
else
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end(fs.readFileSync(file));
});
} else
{
query = unescape(query);
new Session(request, response, query);
}
}).listen(port);
var Session = function(request, response, query)
{
this.request = request;
this.response = response;
var matches = query.match("^(do|get)(\\w+)\\('[^\\(\\)\\\\]+'\\)$");
if (matches === null || matches.length != 3)
{
console.log("invalid query='" +query+"'");
response.writeHead(400, {"Content-Type": "text/plain"});
response.write("400 Bad Request\n");
response.end();
return;
}
var func = matches[1] + matches[2];
if (!this[func] || typeof(this[func]) != "function")
{
console.log("function not found='" +query+"'");
response.writeHead(400, {"Content-Type": "text/plain"});
response.write("400 Bad Request\n");
response.end();
return;
}
eval("this." + query);
}
Session.prototype.getAttendance = function(user, pass, date)
{
if ( pass == "" )
{
this.getAttendanceByName(user, date);
return;
}
attendanceApi.getAttendance(user, pass, date, (function(list)
{
if (list && list.length > 0)
{
list.shift();
this.response.end( list.join("\n") );
} else
{
this.response.writeHead(400, {"Content-Type": "text/plain"});
this.response.write("400 Bad Request\n");
this.response.end();
}
}).bind(this));
}
Session.prototype.getSession = function(user, pass)
{
attendanceApi.getSession(user, pass, (function(session)
{
if (session)
{
this.response.end( session.join("|") );
} else
{
this.response.writeHead(400, {"Content-Type": "text/plain"});
this.response.write("400 Bad Request\n");
this.response.end();
}
}).bind(this));
}
Session.prototype.getAttendanceBySession = function(session)
{
attendanceApi.getAttendanceBySession(session.split("|"), (function(list)
{
if (list && list.length > 0)
{
list.shift();
this.response.end( list.join("\n") );
} else
{
this.response.writeHead(400, {"Content-Type": "text/plain"});
this.response.write("400 Bad Request\n");
this.response.end();
}
}).bind(this));
}
Session.prototype.getAttendanceByName = function(name, date)
{
attendanceApi.getAttendanceByName(name, date, (function(list)
{
if (list && list.length > 0)
{
list.shift();
this.response.end( list.join("\n") );
} else
{
this.response.writeHead(400, {"Content-Type": "text/plain"});
this.response.write("400 Bad Request\n");
this.response.end();
}
}).bind(this));
}
// css
var sheet = document.createElement('style');
sheet.innerHTML = "body {font-family:arial; }";
sheet.innerHTML+= "table { font-size:10px; border-spacing:0px; border-collapse: collapse;}";
sheet.innerHTML+= "td { border:1px solid #ccc; vertical-align:top;}";
sheet.innerHTML+= ".blockRound { height:18px; font-size:11px; float:left;}\n";
sheet.innerHTML+= ".block { height:18px; font-size:11px; float:left; -moz-border-radius: 2px; border-radius: 2px;}\n";
sheet.innerHTML+= ".grad {\n" +
"background: -moz-linear-gradient(-95deg, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0) 100%); /* FF3.6+ */\n" +
"background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0.3)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */\n" +
"background: -webkit-linear-gradient(top, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */\n" +
"background: -o-linear-gradient(top, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0) 100%); /* Opera 11.10+ */\n" +
"}\n"+
".gradside {\n" +
"background: -moz-linear-gradient(left, rgba(255,255,255,0.0) 0%, rgba(255,255,255,0.4) 100%); /* FF3.6+ */\n" +
"background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(100%,rgba(255,255,255,0.3))); /* Chrome,Safari4+ */\n" +
"background: -webkit-linear-gradient(left, rgba(255,255,255,0.0) 0%,rgba(255,255,255,0.3) 100%); /* Chrome10+,Safari5.1+ */\n" +
"background: -o-linear-gradient(left, rgba(255,255,255,0) 0%,rgba(255,255,255,0.3) 100%); /* Opera 11.10+ */\n" +
"}\n"+
".round { -moz-border-radius: 8px; border-radius: 8px; }\n"+
"._00e090 {background: #00e090;}\n" +
"._00ff00 {background: #00ff00;}\n" +
"._00ffd0 {background: #00ffd0;}\n" +
"._ff0000 {background: #ff0000;}\n" +
"._e0e0e0 {background: #e0e0e0;}\n" +
"._ffffff {background: #ffffff;}\n" +
"._ffff00 {background: #ffff00;}\n" +
"._d0d0d0 {background: #d0d0d0;}\n" +
"._b0b0b0 {background: #b0b0b0;}\n" +
"._00b0ff {background: #00b0ff;}\n" +
".fill {height:16px; position:absolute;}" +
".fill:hover {background:rgba(255, 255, 255, 0.5);}"+
"";
document.body.appendChild(sheet);
function mtime(str)
{
if (str.substr(2, 1) != ':')
alert("error");
return parseInt(str.substr(0, 2), 10)*60 + parseInt(str.substr(3, 2), 10);
}
function ftime(val)
{
var pref="";
if (val < 0)
{
pref += "-";
val = -val;
}
return pref+("0"+Math.floor(val/60)).substr(-2)+":"+("0"+(val%60)).substr(-2);
}
function getToday()
{
var date = new Date();
var day = ("0"+date.getDate()).substr(-2);
var month = ("0"+(date.getMonth()+1)).substr(-2);
var today = day+"."+month;
return today;
}
var overall = 0;
var timemin = mtime("06:00");
var timemax = mtime("22:00");
function getoverall()
{
return overall > 0 ? "+"+overall.toString(10) : overall;
}
function htable(data)
{
var out = "";
for (var i=timemin/60; i<timemax/60; i++)
{
var tstart = i*60;
var tend = i*60+60;
out += addtab(tstart, tend, (i%2==0)?"_d0d0d0":"_b0b0b0", "", ftime(tstart));
}
return out;
}
function visual(data)
{
overall = 0;
var o = "";
var today = getToday();
title = "report";
o += "<nobr><div style='float:left; width:100px;'>"+title+"</div>" + htable() + "</div></nobr><br><br>";
for ( var r=0; r<data.length; r++)
{
var date = data[r].day + "." + data[r].month;
var fdateday = new Date(new Date().getFullYear(), data[r].month-1, data[r].day).toString().split(" ")[0];
var fdate = date + " (" + fdateday + ")";
// var fdate = date;
var bToday = date == today;
var dir = [];
var dat = [];
var ext = [];
for ( var i =0; i<data[r].events.length; i++)
{
var event = data[r].events[i];
//console.log(event);
dat.push(event.hour+":"+event.minute);
dir.push(event.event == "P" ? "p" : "o");
ext.push(event.extra);
}
var bWeekend = (fdateday == "Sat") || (fdateday == "Sun");
var bHomeOffice = event.extra.substr(0,1)=="H";
if ( bHomeOffice )
continue;
o += "<nobr><div style='float:left; width:100px;'>" + fdate + "</div>" + table(dir, dat, bToday, ext, bWeekend) + "</nobr><br><BR>";
}
o += "overall: " + getoverall() + " min (" + ftime(getoverall()) + ")<br>";
window.document.title = getoverall() + " min (" + ftime(getoverall()) +")";
return o;
}
function table(dir, data, bToday, ext, bWeekend)
{
var out = "";
if ( data.length == 1 && data[0] == "" )
return out;
var bCorrupt = false;
if (dir[data.length-1].substr(0, 1) == "p")
{
if ( bToday )
{
// dnes
var currentTime = new Date();
data[data.length] = ("0"+currentTime.getHours()).substr(-2) + ":" + ("0"+currentTime.getMinutes()).substr(-2);
dir[dir.length] = "odchod";
} else
{
bCorrupt = true;
}
}
var tlast = timemin; //mtime("06:00");
var total = 0;
var pause = 0;
if ( dir.length != data.length )
return "Error";
for (var i=-1; i<data.length-1; i++)
{
var tinterval = mtime(data[i+1]);
var tdir = i >= 0 ? dir[i] : "o";
var text = i >= 0 ? ext[i] : "";
var desc = i < 0 ? "" : ftime(tlast) + " - " + ftime(tinterval) + " ("+ftime(tinterval-tlast)+")";
if (tdir.substr(0, 1) != "p")
{
if ( tinterval-tlast <= 10 && i > 0 )
{
out += addtab(tlast, tinterval, "_00e090", desc);
total += tinterval - tlast;
}
else
if ( text.substr(0, 1) == "S" ) // sluzebne
{
out += addtab(tlast, tinterval, i > 0 ? "_00ffd0" : "_ffffff", desc);
total += tinterval - tlast;
} else
{
out += addtab(tlast, tinterval, i > 0 ? "_e0e0e0" : "_ffffff", desc);
if (i>0)
pause += tinterval - tlast;
}
}
else
{
out += addtab(tlast, tinterval, bWeekend ? "_00ffd0" : "_00ff00", desc);
total += tinterval - tlast;
}
tlast = tinterval;
}
var visitthresh = mtime("00:45");
var minrequired = mtime("06:00");
var required = mtime("08:00");
var minpause = mtime("00:30");
if ( pause < minpause )
required += minpause - pause;
var diff = total-required;
if ( bWeekend )
diff = 0;
if ( total == 0 )
diff = 0;
if ( total < visitthresh )
diff = 0;
overall += diff;
if ( diff > 0 )
diff = "+"+diff.toString(10);
out += addtab(tlast, timemax, bCorrupt ? "_ff0000" : "_ffffff");
if ( bWeekend )
out += '<div style="float:left; width:70px; text-align:right; color:#000000" title=“Do roboty cez weekend? Si normalny!?”>-</div>';
else if ( bCorrupt )
out += '<div style="float:left; width:70px; text-align:right; color:#ff0000" title="Nebol zaznamenany odchod">* '+ftime(total)+'</div>';
else if ( total == 0 )
out += '<div style="float:left; width:70px; text-align:right; color:#ff0000" title="Nepracoval">* '+ftime(total)+'</div>';
else if ( total < visitthresh )
out += '<div style="float:left; width:70px; text-align:right;" title="Navsteva">* '+ftime(total)+'</div>';
else if ( total < minrequired )
out += '<div style="float:left; width:70px; text-align:right; color:#ff0000" title="Nebolo odpracovanych 6 hodin">* '+ftime(total)+'</div>';
else if ( total < required )
out += '<div style="float:left; width:70px; text-align:right; color:#ff0000">'+ftime(total)+'</div>';
else
out += '<div style="float:left; width:70px; text-align:right;">'+ftime(total)+'</div>';
if ( diff != 0 )
out += '<div style="float:left; width:45px; text-align:right; color:#b0b0b0; font-size:10px;">'+diff+' min</div>';
return out;
}
function addtab(start, end, clr, tip, cont)
{
var len = (end-start)/2;
if ( len < 1 )
return '';
if ( typeof(cont) == 'undefined' )
cont = '';
if ( typeof(tip) == 'undefined' )
tip = '';
else
tip = 'title="'+tip+'"';
var size = "width:"+len+"px;";
var style = /*(tip == "") ?*/ (cont != '') ? "block" : "blockRound";
if ( style == "block" )
return ('<div '+tip+' class="'+clr+' '+style+'" style="position:relative; '+size+'">'+cont+'</div>');
if ( clr == "_ffffff" )
return ('<div '+tip+' class="round '+style+' '+clr+'" style="position:relative; '+size+'">'+cont+'</div>');
var o = "";
o += '<div class="'+style+'" style="position:relative; '+size+'">';
o += '<div class="round fill '+clr+'" style="'+size+'">'+cont+'</div>';
o += '<a '+tip+' href="javascript:;">';
o += '<div class="round fill grad" style="position:absolute;'+size+'"></div>';
o += '<div class="round fill gradside" style="position:absolute;'+size+'"></div>';
o += '</a>';
o += '</div>';
return o;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment