Mercurial > hg > lukkari
view index.php @ 151:ca012374190c
Fix update script to work with dash/non-bash shells.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 25 Sep 2014 19:27:34 +0300 |
parents | 5c0eacb7d35d |
children | 9c6290ad087d |
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 "msitegen.inc.php"; // Default settings $pageName = "OAMK Lukkari"; $pageVersion = "2.3"; $mobileMode = FALSE; $baseURI = "http://example.com/"; $pageLanguages = array("fi", "en"); $pageCSSData = array("cookie" => "lukcss", "prefix" => "luk"); $classDefaultID = "DEFAULT"; $classIDFile = "classes.txt"; $courseCacheFile = "coursecache.txt"; if (file_exists("config.inc.php")) @require "config.inc.php"; // // Hardcoded tables // $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! %2 v%1 is still under development. There may be bugs.", "fi" => " HUOM! %2 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.", ), "vuoroviikoin" => array( "en" => "Every other week", "fi" => "Vuoroviikoin", ), "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 noin 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 ". "approximately 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 $classDefaultID; 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", $classDefaultID)); $id = $classDefaultID; 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 lukClassGetHourStr($start, $end) { global $classHourTimes; return lukGetHourStamp($classHourTimes[$start]["start"]). " - ". lukGetHourStamp($classHourTimes[$end]["end"]); } function lukMatchCourse($id) { global $cache, $cacheDirty, $pageCharset, $pageLang, $mobileMode; //$uri = "http://www.oamk.fi/opiskelijalle/rakenne/opinto-opas/koulutusohjelmat/?sivu=oj&kieli=".strtoupper($pageLang)."&koodi1=".$id; $uri = "http://www.oamk.fi/koulutus_ja_hakeminen/opiskelu_oamkissa/opinto-opas/koulutusohjelmat/?sivu=oj_kuvaus&koodi1=".$id."&kieli=".strtoupper($pageLang); // 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])) { if ($mobileMode) { return "<b>".chentities($cache[$id][$pageLang]["desc"])."</b>"; } else { 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($class) { $data = $class["data"]; if ($class["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>"; } $out .= "</table>"; if ($class["turns"]) $out .= cmQM("vuoroviikoin"); return $out; } else { $out = lukMatchCourse($data[0][0])."<br />"; for ($i = 1; $i < count($data[0]); $i++) { $out .= chentities($data[0][$i])."<br />"; } if ($class["turns"]) $out .= cmQM("vuoroviikoin"); 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 id=\"timeTable\">\n". " <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 id=\"timeTable\">\n". " <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"]."\" ". "title=\"".lukClassGetHourStr($hour, $hour + $class["hours"] - 1)."\" class=\"". ($isActive ? "clactive " : ""). (!$isActive && $nextActive ? "clnext " : ""). (($class["grouped"] || $class["turns"]) ? "clgrouped" : "clnormal")."\">". lukGetClassInfo($class). "<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 (($tmp = stGetRequestItem("lang", FALSE, TRUE)) !== FALSE) { $tmp = strtolower($tmp); 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 class setting if (($classID = stGetRequestItem("luokka", FALSE, TRUE)) !== FALSE && lukCheckClassID($classID)) { setcookie("lukluokka", $classID, time() + 365*24*60*60); // expire in a year } else if (isset($_COOKIE["lukluokka"])) { $classID = $_COOKIE["lukluokka"]; lukCheckClassID($classID); } else { stError(cmQM("classNotSet", $classDefaultID)); $classID = $classDefaultID; } // Check next period flag if (isset($_REQUEST["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 (($classIDs = lukReadClassFile($classIDFile, &$timestamp)) === false) stError(cmQM("classListNotFound")); // Read class data $dataFile = $cachePath.$classID.".data"; if (!file_exists($dataFile)) { stError(cmQM("classDataNotFound", chentities($classID))); $haveData = FALSE; } else { require($dataFile); $haveData = isset($classInfo); } // 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 $pageTitle = $haveData ? $classID." / ".join("; ", $classInfo["info"]) : $classID; cmPrintPageHeader($pageTitle." - ".$pageName, $extra); // Info box echo "<div id=\"infobox\">\n". " <div id=\"ctitle\">".$pageName." v".$pageVersion."</div>\n"; if (!$mobileMode) { echo " <div id=\"csssel\">".cmQM("Style").": "; if (isset($pageCSSAlts)) { 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"; if ($classIDs !== FALSE) { foreach ($classIDs as $id) { echo " <option ".($classID == $id ? "selected=\"selected\" " : ""). "value=\"".$id."\">".chentities($id)."</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"; if ($haveData) { echo " <th><a id=\"orig\" class=\"textctrl\" href=\"".$origBaseURI.$classID.$origBaseExt."\">".cmQM("Original")."</a></th>\n"; //" <th><a id=\"xml\" class=\"textctrl\" href=\"".$baseURI.$cachePath."/".$luokka.".xml\">XML</a></th>\n"; } echo " <th><a class=\"textctrl mobile\" href=\"http://tnsp.org/mluk/\">Mobile</a></th>\n"; } $currURL = $baseURI."?luokka=".$classID."&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("%d.%m.%Y, %H:%M", $timestamp)). //" <div style=\"color: red;\">".cmQM("beta", $pageVersion, $pageName)."</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 .. } } ?>