Mercurial > hg > lukkari
view index.php @ 130:7cfe0770168f
Sync infobox snippets from mluk.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 27 Aug 2014 16:42:00 +0300 |
parents | b9ebc24f27fd |
children | 31347f83cbea |
line wrap: on
line source
<?php // // OAMK Lukkari v2.3 // (C) Copyright 2010 - 2014 Matti 'ccr' Hämäläinen <ccr@tnsp.org> // Yes, this code is rather horrible. :| // // Include framework require "mcommon.inc.php"; $pageVersion = "2.3"; $baseURI = "http://tnsp.org/luk/"; $pageLang = "fi"; $pageLanguages = array("fi", "en"); $pageCSSData = array("cookie" => "lukcss", "prefix" => $baseURI."luk"); $pageCSSAlts = array("blue" => "1", "old" => "2", "purple" => "3", "dark" => "4"); $classDefault = "TTE1SNO"; $classIDFile = "classes.txt"; $courseCacheFile = "coursecache.txt"; $lukDayNames = array( "fi" => array("Maanantai", "Tiistai", "Keskiviikko", "Torstai", "Perjantai", "Lauantai", "Sunnuntai"), "en" => array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"), ); $pageTranslations = array( "Original" => array("fi" => "Alkuperäinen"), "Shown" => array("fi" => "Näkyvillä"), "Next period" => array("fi" => "Seuraava periodi"), "Current period" => array("fi" => "Nykyinen periodi"), "Switch" => array("fi" => "Vaihda"), "contact" => array( "en" => "Contact <b>%1</b> or <b>%2</b>. The author can't be held responsible for any errors or inaccuracies in the data!", "fi" => "Yhteydenotot <b>%1</b> tai <b>%2</b>. En vastaa mahdollisista virheistä tai epätarkkuuksista tiedoissa!", ), "updated" => array( "en" => "Last updated: <b>%1</b>.", "fi" => "Päivitetty: <b>%1</b>.", ), "beta" => array( "en" => " NOTICE! OAMK Lukkari v%1 is still under development. There may be bugs.", "fi" => " HUOM! OAMK Lukkari v%1 on vielä kehityksen alla. Bugeja voi löytyä.", ), "viikossa" => array( "en" => "Total of <b>%1</b> hours in the week.", "fi" => "Viikossa yhteensä <b>%1</b> tuntia.", ), "classNotSet" => array( "en" => "Class not set, using default <b>%1</b>.", "fi" => "Luokkaa ei asetettu, käytetään vakioarvoa <b>%1</b>.", ), "classDataNotFound" => array( "fi" => "Luokan %1 tietoja ei löytynyt! Jos luokkakoodi on uusi, ". "ilmestyy se järjestelmään seuraavan päivityksen aikana. Luokkatiedot ". "päivitetään kerran viikossa.", "en" => "Data for class %1 was not found. If the class code is new, it ". "should appear in this system during the next update. The data is updated ". "once per week.", ), "classListNotFound" => array( "fi" => "Luokkien listaa ei löytynyt. Kokeile ladata sivu uudelleen hetken kuluttua.", "en" => "Class list not found. An update may be in progress, try reloading in a minute.", ), "classFormatError" => array( "fi" => "Virhe! Luokan täytyy olla muotoa <b>XXXnXXX</b>, käytetään vakioarvoa <b>%1</b>.", "en" => "Error! Class code must be of format <b>XXXnXXX</b>, using default value of <b>%1</b>.", ), "Style" => array( "fi" => "Tyyli", ), "currLukLink" => array( "fi" => "Linkki tähän lukujärjestykseen nykyisillä asetuksilla (kieli, jne.)", "en" => "Link to the this timetable with current settings (language, etc.)", ), // "" => array("fi" => ), ); function lukGetDayName($day) { global $lukDayNames, $pageLang; if (isset($lukDayNames[$pageLang]) && isset($lukDayNames[$pageLang][$day])) return $lukDayNames[$pageLang][$day]; else return $lukDayNames["en"][$day]; } function lukCheckClassID(&$id) { global $classDefault; if (preg_match("#^([A-Z]{3}\d[A-Za-z0-9_]{1,6}|ccr|Ryh_[A-Z]{3}\d[A-Za-z0-9_]{1,6})$#", $id, $m)) { $id = $m[1]; return TRUE; } else { stError(cmQM("classFormatError", $classDefault)); $id = $classDefault; return FALSE; } } function lukGetWeekdayFromTimestamp($stamp) { $info = getdate($stamp); $day = $info["wday"]; return ($day > 0) ? $day - 1 : $day + 6; } function lukGetHourStamp($stamp) { return date("H:i", mktime(0, 0, $stamp, 0, 0, 0)); } function lukGetHourStr($hour) { global $classHourTimes; if (isset($classHourTimes[$hour])) { return "<br />". lukGetHourStamp($classHourTimes[$hour]["start"]). " - ". lukGetHourStamp($classHourTimes[$hour]["end"]). "<br /><br />"; } else return "ERROR"; } function lukMatchCourse($id) { global $cache, $cacheDirty, $pageCharset, $pageLang; $uri = "http://www.oamk.fi/opiskelijalle/rakenne/opinto-opas/koulutusohjelmat/?sivu=oj&kieli=".strtoupper($pageLang)."&koodi1=".$id; // Create the index if (!isset($cache[$id])) $cache[$id] = array(); // Check if course exists in cache if (!isset($cache[$id][$pageLang])) { // Not cached, try to fetch data $cacheDirty = TRUE; $data = @file_get_contents($uri); if ($data !== FALSE) { $data = @iconv("iso-8859-15", $pageCharset, $data); if (preg_match("#<td class=\"smallheadercell\"><strong>(.+?)\s+(\d+)\s*(op|ECTS\s+cr)\s*</strong></td>#", $data, $m)) { // Add data to cache $cache[$id][$pageLang] = array("desc" => $m[1], "op" => intval($m[2])); } } } if (isset($cache[$id]) && isset($cache[$id][$pageLang])) { return "<a target=\"_blank\" title=\"".chentities($id." - ".$cache[$id][$pageLang]["op"]." op"). "\" href=\"".chentities($uri)."\">".chentities($cache[$id][$pageLang]["desc"])."</a>"; } else return chentities($id); } function lukGetClassInfo($grouped, $data) { if ($grouped) { $out = "<table><tr>"; $maxCount = 0; foreach ($data as $col) { $out .= "<td>".lukMatchCourse($col[0])."</td>"; if (count($col) > $maxCount) $maxCount = count($col); } $out .= "</tr>"; for ($i = 1; $i < $maxCount; $i++) { $out .= "<tr>"; foreach ($data as $col) { $out .= "<td>"; if (isset($col[$i])) $out .= chentities($col[$i]); $out .= "</td>"; } $out .= "</tr>"; } return $out."</table>"; } else { $out = lukMatchCourse($data[0][0])."<br />"; for ($i = 1; $i < count($data[0]); $i++) { $out .= chentities($data[0][$i])."<br />"; } return $out; } } function lukFindClass($day, $hour) { global $classHourDefs, $classDayTable; if (isset($classDayTable[$day])) { foreach ($classDayTable[$day] as $id) { if ($hour >= $classHourDefs[$id]["start"] && $hour < $classHourDefs[$id]["start"] + $classHourDefs[$id]["hours"]) return $id; } } return 0; } function lukReadClassFile($filename, &$mtimestamp) { // Attempt to open file for reading if (($fp = @fopen($filename, "rb")) === false) return false; $mtimestamp = filemtime($filename); $mclasses = FALSE; // Lock file so that we do not get clashes if (flock($fp, LOCK_SH)) { $mclasses = array(); // Read and parse data while (!feof($fp)) { $str = trim(fgets($fp, 128)); if (strlen($str) > 2 && $str[0] != "#") $mclasses[] = $str; } // Release lock flock($fp, LOCK_UN); } fclose($fp); return $mclasses; } function lukPrintTimeTable($mini) { global $classInfo, $classHourDefs, $classHourTimes; // $currStamp = time() + ((3 * 60) + 45) * 60; $currStamp = time(); $currTime = $currStamp - mktime(0, 0, 0); $currDay = lukGetWeekdayFromTimestamp($currStamp); $nextStamp = $currStamp + 30 * 60; $nextTime = $nextStamp - mktime(0, 0, 0); // Create the timetable table if ($mini) { $out = "<table class=\"timetable\">". " <tr>\n <th></th>". " <th class=\"days\">".lukGetDayName($currDay)."</th>\n </tr>\n"; $startDay = $currDay; $lastDay = $currDay + 1; } else { $out = "<p>".join("; ", $classInfo["general"]). //" [".cmQM("viikossa", $classInfo["totalHours"])."]". "</p>\n". "<table class=\"timetable\">". " <tr>\n <th></th>\n"; $cellWidth = $classInfo["maxDays"] > 0 ? 100 / $classInfo["maxDays"] : 15; if ($cellWidth > 25) $cellWidth = 25; for ($day = 0; $day < $classInfo["maxDays"]; $day++) { $out .= " <th style=\"width: ".$cellWidth."%;\" class=\"days\">".lukGetDayName($day)."</th>\n"; } $out .= " </tr>\n"; $startDay = 0; $lastDay = $classInfo["maxDays"]; } for ($hour = $classInfo["firstHour"]; $hour < $classInfo["lastHour"]; $hour++) { $out .= " <tr>\n". " <th class=\"hours\">".lukGetHourStr($hour)."</th>\n"; for ($day = $startDay; $day < $lastDay; $day++) { $id = lukFindClass($day, $hour); if ($id > 0) { $class = &$classHourDefs[$id]; if (!isset($class["set"])) { $class["set"] = TRUE; $nextActive = $day == $currDay && $nextTime >= $classHourTimes[$class["start"]]["start"] && $nextTime < $classHourTimes[$class["start"] + $class["hours"] - 1]["end"]; $isActive = $day == $currDay && $currTime >= $classHourTimes[$class["start"]]["start"] && $currTime < $classHourTimes[$class["start"] + $class["hours"] - 1]["end"]; $out .= " <td rowspan=\"".$class["hours"]."\" class=\"". ($isActive ? "clactive " : ""). (!$isActive && $nextActive ? "clnext " : ""). ($class["grouped"] ? "clgrouped" : "clnormal")."\">". lukGetClassInfo($class["grouped"], $class["data"]). "<div class=\"nhours\"><span>".$class["hours"]."h</span></div></td>\n"; } } else { $out .= " <td class=\"clnothing\"></td>\n"; } } $out .= " </tr>\n"; } return $out."</table>\n"; } // // Main code begins // // Check given parameters: // Language must be the first setting to be validated, // so that the translation support works properly. // if (isset($_GET["lang"])) { $tmp = strtolower($_GET["lang"]); if (in_array($tmp, $pageLanguages)) { $pageLang = $tmp; setcookie("luklang", $tmp, time() + 365*24*60*60); // expire in a year } } else if (isset($_COOKIE["luklang"])) { $tmp = $_COOKIE["luklang"]; if (in_array($tmp, $pageLanguages)) $pageLang = $tmp; } // Check if we are using mobile mode $mobileMode = FALSE; /* if (isset($_GET["m"])) { $mobileMode = intval($_GET["m"]); setcookie("lukmobile", $mobileMode, time() + 365*24*60*60); // expire in a year } else if (isset($_COOKIE["lukmobile"])) { $mobileMode = $_COOKIE["lukmobile"]; } if ($mobileMode) { $pageCSSData["prefix"] = $baseURI."mluk"; } */ // Check class setting if (isset($_GET["luokka"])) { $luokka = $_GET["luokka"]; if (lukCheckClassID($luokka)) { setcookie("lukluokka", $luokka, time() + 365*24*60*60); // expire in a year } } else if (isset($_COOKIE["lukluokka"])) { $luokka = $_COOKIE["lukluokka"]; lukCheckClassID($luokka); } else { stError(cmQM("classNotSet", $classDefault)); $luokka = $classDefault; } // Check next period flag if (isset($_GET["next"])) { $nextPeriod = TRUE; $cachePath = "cache-next/"; } else { $nextPeriod = FALSE; $cachePath = "cache/"; } if (file_exists($cachePath."baseuri.data")) { require $cachePath."baseuri.data"; } // Global cache for course data $cache = array(); $cacheDirty = FALSE; // Try to read cachefile, if we can get file lock on it $fp = @fopen($courseCacheFile, "rb"); if ($fp) { if (flock($fp, LOCK_SH)) { require($courseCacheFile); flock($fp, LOCK_UN); } fclose($fp); } // Read classfile if (($classes = lukReadClassFile($classIDFile, &$timestamp)) === false) stError(stQM("classListNotFound")); // Read class data $dataFile = $cachePath.$luokka.".data"; if (!file_exists($dataFile)) { stError(cmQM("classDataNotFound", chentities($luokka))); $haveData = FALSE; } else { require($dataFile); $haveData = isset($classInfo); } // Set some variables $pageTitle = $haveData ? $luokka." / ".join("; ", $classInfo["info"]) : $luokka; // Create references to mobile device (Apple touch) icons $extra = ""; foreach (array(57 => FALSE, 76 => TRUE, 114 => TRUE, 120 => TRUE, 152 => TRUE) as $iconSize => $addSize) { $extra .= " <link rel=\"apple-touch-icon\" ". ($addSize ? "sizes=\"".$iconSize."x".$iconSize."\" " : ""). "href=\"img/icon-".$iconSize."-precomposed.png\" />\n"; } // Start printing the page cmPrintPageHeader($pageTitle, $extra); // Info box echo "<div id=\"infobox\">\n". " <div id=\"ctitle\">OAMK Lukkari v".$pageVersion."</div>\n"; if (!$mobileMode) { echo " <div id=\"csssel\">".cmQM("Style").": "; foreach ($pageCSSAlts as $name => $id) { echo "<a ".(($pageCSSIndex == $id) ? " class=\"selected\"" : ""). "href=\"".$baseURI."?css=".$id."\">".$name."</a>"; } echo "</div>\n"; } echo " <div id=\"clang\">"; foreach ($pageLanguages as $id) { echo "<a ".(($pageLang == $id) ? " class=\"selected\"" : ""). "href=\"".$baseURI."?lang=".$id."\">".$id."</a>"; } echo "</div>\n". "</div>\n"; // Additional controls echo "<form id=\"controls\" action=\"".$baseURI."\" method=\"get\">\n". " <table>\n". " <tr>\n". " <th>\n". " <select name=\"luokka\">\n"; foreach ($classes as $class) { echo " <option ".($luokka == $class ? "selected=\"selected\" " : ""). "value=\"".$class."\">".chentities($class)."</option>\n"; } echo " </select>\n". " </th>\n". " <th><input class=\"submit\" type=\"submit\" value=\"".cmQM("Switch")."\" /></th>\n"; if (!$mobileMode) { echo " <th><a id=\"next\" class=\"textctrl\" href=\"".$baseURI.($nextPeriod ? "" : "?next")."\">". cmQM("Shown").": ".($nextPeriod ? cmQM("Next period") : cmQM("Current period")). "</a></th>\n". " <th><a id=\"orig\" class=\"textctrl\" href=\"".$origBaseURI.$luokka.$origBaseExt."\">".cmQM("Original")."</a></th>\n". // " <th><a id=\"xml\" class=\"textctrl\" href=\"".$baseURI.$cachePath."/".$luokka.".xml\">XML</a></th>\n". " <th><a class=\"textctrl mobile\" href=\"http://tnsp.org/mluk/\">Mobile</a></th>\n"; } $currURL = $baseURI."?luokka=".$luokka."&lang=".$pageLang. (isset($pageCSSIndex) ? "&css=".$pageCSSIndex : ""). ($nextPeriod ? "&next" : ""); echo " <th><a href=\"".$currURL."\" class=\"textctrl\" title=\"".cmQM("currLukLink")."\">Link</a></th>\n". // " <th class=\"advert\"><a href=\"http://tnsp.org/u/HXh\"><img src=\"img/cell.png\" alt=\"Division Cell\" /></a></th>\n". " <th class=\"advert\"><a href=\"http://tnsp.org/u/G1X\"><img src=\"img/hdd_fi.gif\" alt=\"HDD.fi\" /></a></th>\n". " </tr>\n". " </table>\n". "</form>\n". "<h1>".$pageTitle."</h1>\n"; // Show error messages if ($errorSet) { echo "<ul>\n"; foreach ($errorMsgs as $msg) echo "<li>$msg</li>\n"; echo "</ul>\n"; } if ($haveData) { echo lukPrintTimeTable($mobileMode); } echo "<div id=\"footer\">". cmQM("contact", "ccr @ IRCNet", "ccr (at) tnsp (dot) org"). " / ". cmQM("updated", strftime("%m.%d.%Y, %H:%M", $timestamp)). //" <div style=\"color: red;\">".cmQM("beta", $pageVersion)."</div>\n". "</div>\n"; cmPrintPageFooter(); // Dump the course data cache, but only if it has changed if ($cacheDirty) { $str = "<?\n\$cache = ".var_export($cache, TRUE)."\n?>"; if (file_put_contents($courseCacheFile, $str, LOCK_EX) === FALSE) { // Can't do much anything here .. } } ?>