Files
solon/server/fetch.php
T

237 lines
6.9 KiB
PHP

<?php
# API logic
// 1. make login request
// 2. call the desired function (get specific page)
// 3. parse that page into a json file
// 4. return that json file to the caller
require 'vendor/autoload.php';
use Goutte\Client;
use Symfony\Component\DomCrawler\Crawler;
$client = new Client();
function make_login_request($username, $password) {
global $client;
$url = "https://aplikace.skolaonline.cz/SOL/Prihlaseni.aspx";
$headers = [
"__EVENTTARGET" => "dnn\$ctr994\$SOLLogin\$btnODeslat",
"__EVENTARGUMENT" => "",
"__VIEWSTATE" => "",
"__VIEWSTATEGENERATOR" => "",
"__VIEWSTATEENCRYPTED" => "",
"__PREVIOUSPAGE" => "",
"__EVENTVALIDATION" => "",
"dnn\$dnnSearch\$txtSearch" => "",
"JmenoUzivatele" => $username, # username
"HesloUzivatele" => $password, # password
"ScrollTop" => "",
"__dnnVariable" => "",
"__RequestVerificationToken" => ""
];
$client->request("POST", $url, $headers=$headers);
if ($client->getResponse()->getStatusCode() != 200) {
return false;
} else {
return true;
}
}
function parse_teacher($onmouseover) {
if ($onmouseover == null) {
$onmouseover = "Učitel:~ ~";
}
$explode_on_teacher = explode("Učitel:", $onmouseover); // [0] => something, [1] => teacher and something, 0 can be ignored
$explode_on_first_tilda = explode("~", $explode_on_teacher[1]);
$explode_on_second_tilda = explode("~", $explode_on_first_tilda[1]);
$teacher = $explode_on_second_tilda[0];
if (strstr($teacher, ">")) {
$teacher = explode("<", explode(">", $teacher)[1])[0];
}
return $teacher;
}
function get_time($times, $index) {
foreach ($times as $cell) {
$current_hour = explode(".", $cell->filter(".KuvHeaderNadpis")->text())[0];
if ($index == $current_hour) {
return explode(" - ", $cell->filter(".KuvHeaderText")->text());
}
}
}
function parse_substitute($substitutes) {
if ($substitutes->count() == 0) {
return 0;
} else {
return 1;
}
}
function parse_cell($cell, $cell_counter, $times) {
$is_empty = false;
if ($cell->filter(".KuvBunkaRozvrhNadpis")->count() == 0) {
$is_empty = true;
}
if (!$is_empty && $cell->filter("table")->filter(".KuvSuplovanaHodina")->count() == 0) {
$name = $cell->filter(".KuvBunkaRozvrhNadpis")->first()->text();
$maybe_place = $cell->filter(".KuvBunkaRozvrhText")->first()->html();
if ($maybe_place == null) {
$maybe_place = "<br>";
}
$place = explode("<br>", $maybe_place)[1];
if ($place == null) {
$place = "";
}
$teacher = parse_teacher($cell->filter("table")->filter("td")->first()->attr("onmouseover"));
$is_substitute = parse_substitute($cell->filter(".KuvSuplujiciHodina"));
$number = $cell_counter;
$start = get_time($times, $cell_counter)[0]; // gives [start, end]
$end = get_time($times, $cell_counter)[1];
return [
"name" => $name,
"place" => $place,
"teacher" => $teacher,
"is_substitute" => $is_substitute,
"number" => $number,
"start" => $start,
"end" => $end
];
} else {
$number = $cell_counter;
$start = get_time($times, $cell_counter)[0];
$end = get_time($times, $cell_counter)[1];
return [
"name" => "Volno",
"place" => "Volno",
"teacher" => "Volno",
"is_substitute" => "Volno",
"number" => $number,
"start" => $start,
"end" => $end
];
}
}
function parse_cal_week($crawler) {
$week = [];
$table = $crawler->filter("#CCADynamicCalendarTable");
$rows_ = $table->filter("tr");
$times_ = $rows_->first()->filter("th");
$times = [];
$rows = [];
$rows_->each(function (Crawler $node, $i) use (&$rows) {
$rows[] = $node;
});
array_shift($rows);
$times_->each(function (Crawler $node, $i) use (&$times) {
$times[] = $node;
});
array_shift($times);
foreach ($rows as $row) { // for every day do:
$filtered_names = $row->filter(".KuvHeaderNadpis");
$filtered_dates = $row->filter(".KuvHeaderText");
if ($filtered_names->count() > 0 && $filtered_dates->count() > 0) {
$name = $filtered_names->first()->text();
$date = $filtered_dates->first()->text();
$subjects = [];
$cells_ = $row->filter(".DctCell");
$cells = [];
$cells_->each(function (Crawler $node, $i) use (&$cells) {
$cells[] = $node;
});
$cell_counter = 1; // start from 1
foreach ($cells as $cell) {
$subject = parse_cell($cell, $cell_counter, $times);
$colspan = $cell->attr("colspan");
$cell_counter += 1;
if ($colspan != null) {
array_push($subjects, $subject);
for ($i = 1; $i < $colspan; $i++) {
$subject = parse_cell($cell, $cell_counter, $times);
$cell_counter += 1;
array_push($subjects, $subject);
}
} else {
array_push($subjects, $subject);
}
}
// get rid of trash lectures from the end
while ($subjects[count($subjects)-1]["name"] == "Volno") {
array_pop($subjects);
}
$day = [
"name" => $name,
"date" => $date,
"subjects" => $subjects
];
array_push($week, $day);
}
}
return $week;
}
function get_cal_week() {
global $client;
$url = "https://aplikace.skolaonline.cz/SOL/App/Kalendar/KZK001_KalendarTyden.aspx";
$crawler = $client->request("GET", $url);
if ($client->getResponse()->getStatusCode() != 200) {
return "Could not fetch weelky calendar data";
} else {
return parse_cal_week($crawler);
}
}
function create_json_file($body, $status_code) {
$json = ["body" => $body, "status_code" => $status_code];
return json_encode($json);
}
if (!isset($_POST["username"]) || !isset($_POST["password"])) {
echo create_json_file(json_encode("Credentials not supplied"), 1); // status 1 => failure
} else {
if (!make_login_request($_POST["username"], $_POST["password"])) {
echo create_json_file("Invalid credentials", 1);
}
if ($_POST["cal_week"]) {
echo create_json_file(get_cal_week(), 0);
}
#if ($_POST["cal_tdy_tmr"]) {
# echo create_json_file(get_cal_tdy_tmr(), 0);
#}
#if ($_POST["grades"]) {
# echo create_json_file(get_grades(), 0);
#}
}
?>