/* * Copyright (C) 2014 * This file is part of WvS VPlan. * * WvS VPlan is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ // Login-Popup beim Start $(document).bind('pageinit', function(){ setTimeout(function(){ fillform(); load(); }, 1000); setTimeout(function(){ trylogin(); }, 2000); }); /* der Loader wird nur angezeigt, wenn das Popup zu ist */ $('#loginpopup').on('popupafteropen', function(){ $.mobile.loading('hide'); }); /* füllt die Loginform mit gespeicherten Werten */ function fillform(){ var username = window.localStorage.getItem('username'); if(username !== 'undefined' && username != null && username != ''){ $('#username').val(username); } var password = window.localStorage.getItem('password'); if(password !== 'undefined' && password != null && password != ''){ $('#password').val(password); } } function parseVertretungen(str){ var vertretungen_re = new RegExp('(\\w+)\\s+(\\d(?:\\s+-\\s+\\d)?)\\s+((?:x\\s+)?)(\\+|\\w+|---)\\s+(\\w+|---)\\s+(\\w+|---)\\s+(.*?)\\s+(\\w+)(?:\\s+)?(.*?)'); var res; var vertretungen = []; console.log(vertretungen_re.toString()); str.split('\n').forEach(function(vertretungsstr){ res = vertretungsstr.match(vertretungen_re) if(res !== null){ var klasse = res[1]; var stunde = res[2].replace(/ /g, ''); var entfall = res[3].indexOf('x') > -1; var vertreter = res[4]; var fach = res[5]; var raum = res[6]; var art = res[7]; var lehrer = res[8]; var info = res[9]; if(entfall == true){ if(art.length <= 1){ art = ""; }else{ art = " " + art; } if(info.length <= 1){ info = ""; }else{ info = " Info:" + info; } vertretungen.push(klasse + " " + stunde + ". Stunde Entfall statt " + lehrer + art + info); }else{ if(art.length <= 1){ art = ""; }else{ art = art + " in "; } if(info.length <= 1){ info = ""; }else{ info = " Info:" + info; } var nlehrer; if(lehrer != vertreter){ nlehrer = " bei " + vertreter + " (statt " + lehrer + ")"; } vertretungen.push(klasse + " " + stunde + ". Stunde " + art + fach + nlehrer + " in Raum " + raum + info); } } }); console.log(JSON.stringify(vertretungen)); return vertretungen; } /* PDF Rendering */ function renderPage($div, pdf, pageNumber, callback){ pdf.getPage(pageNumber).then(function(page){ var scale = 1; var viewport = page.getViewport(scale); var pageDisplayWidth = viewport.width; var pageDisplayHeight = viewport.height; var $pageDivHolder = $('
'); $pageDivHolder.addClass('pdfpage'); $pageDivHolder.width($(window).width()) // TODO Rotation change $pageDivHolder.height($(window).height()); var $canvas = $(''); var canvas = $canvas.get(0); canvas.className = 'pdfcanvas'; var context = canvas.getContext('2d'); canvas.width = pageDisplayWidth; canvas.height = pageDisplayHeight; $pageDivHolder.append(canvas); $div.append($pageDivHolder); var renderContext = { canvasContext: context, viewport: viewport }; page.render(renderContext).promise.then(function(pdf){ page.getTextContent().then(function(textContent){ // Text extrahieren var page_text = ""; var last_block = null; for(j = 0; j < textContent.length; j++){ var block = textContent[j]; if(last_block != null && last_block.str[last_block.str.length - 1] != ' '){ if(block.x < last_block.x){ page_text += '\n'; }else if(last_block.y != block.y && (last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null )){ page_text += '\n'; } } page_text += block.str; last_block = block; } var highlights = []; var vertretungen = parseVertretungen(page_text); var username = getuserdata()[0]; if(username !== null){ var klasse = username.match(/(\w+)_.*/); if(klasse !== null){ vertretungen.forEach(function(vertretung){ if(vertretung.indexOf(klasse[1]) > -1){ hightlights.push(vertretung); console.log('Wichtige Vertretung: ' + vertretung); } }); } } // TODO mach etwas mit den Vertretungen }); callback(pdf); }); }); } function render_pdf(url, divstr){ console.log('Rendere PDF: ' + url + ' (' + divstr + ')'); PDFJS.getDocument(url).then(function(pdf){ var $viewer = $('#' + divstr); var pageNumber = 1; renderPage($viewer, pdf, pageNumber++, function pageRenderingComplete(){ if(pageNumber > pdf.numPages){ $.mobile.loading('hide'); // nach dem Rendern des ersten PDFs Loader verstecken return; } renderPage($viewer, pdf, pageNumber++, pageRenderingComplete); }); }); } /* wird bei Verbindungsfehlern oder anderen Fehlern aufgerufen */ function fail(text){ $('#lnklogin').click(); $('#error_noconn').show('fast'); console.log('Fehler: ' + text.toString() + ' / ' + text.code); } /* entfernt das Logintab */ function removelogintab(){ $('#vplannavbar').find('*').andSelf().each(function(){ $(this).removeClass(function(i, cn){ var matches = cn.match(/ui-[\w\-]+/g) || []; return (matches.join(' ')); }); if($(this).attr('class') == ''){ $(this).removeAttr('class'); } }); $('#vplannavbar').navbar('destroy'); $('#vplannavbar ul li:first').remove(); $('#vplannavbar').navbar(); $('#login').remove(); $('#vplantabs').tabs('refresh'); } function replaceUmlauts(umlautstr){ tr = {'ä': 'ae', 'ü': 'ue', 'ö': 'oe', 'ß': 'ss'}; return umlautstr.replace(/[äöüß]/g, function($0) { return tr[$0]; }); } /* fügt die lokale URL des Plans ein und ruft die Seite zum Rendering auf */ function addplanattr(fileEntry, wasdownloaded){ var sPath = fileEntry.toURL(); var name = fileEntry.name; console.log('Dateiname: ' + name); var fname_re = new RegExp('.*?(\\d{4})-(\\d{2})-(\\d{2})(.*?)\\.pdf'); var results = name.match(fname_re); if(results[4] !== null){ results[4] = results[4].replace(/[ ,]/g, '-').replace(/-{2}/g, '-'); } name = results[3] + '_' + results[2] + '_' + results[1] + results[4]; name = replaceUmlauts(name); // TODO console.log(name); if(!$(name).length){ $('#vplannavbar').find('*').andSelf().each(function(){ $(this).removeClass(function(i, cn){ var matches = cn.match(/ui-[\w\-]+/g) || []; return (matches.join(' ')); }); if($(this).attr('class') == ''){ $(this).removeAttr('class'); } }); $('#vplannavbar').navbar('destroy'); $('#vplannavbar ul').append('
  • ' + name.replace(/_/g, '.') + '
  • '); $('#vplannavbar').navbar(); $('#vplantabs').append('
    '); $('#vplantabs').tabs('refresh'); if($('#login').length && wasdownloaded){ removelogintab(); } } render_pdf(sPath, name); } /* lädt ein PDF anhand eines Links herunter, benötigt ID zur Sortierung */ function download_pdf(link){ var filename = link.substring(link.lastIndexOf("/") + 1); window.requestFileSystem( LocalFileSystem.PERSISTENT, 0, function(fileSystem){ fileSystem.root.getDirectory('WvSVPlan', {create: true, exclusive: false}, function(dirEntry){ dirEntry.getFile(filename, {create: false, exclusive: false}, function(fileEntry){ // Datei ist schon heruntergeladen console.log('Datei schon heruntergeladen'); if($('#login').length){ removelogintab(); } }, function(err){ // Datei existiert noch nicht dirEntry.getFile(filename, {create: true, exclusive: false}, function(fileEntry){ var fileTransfer = new FileTransfer(); fileTransfer.download( link, fileEntry.toURL(), function(theFile){ console.log('Download fertig: ' + theFile.toURL()); addplanattr(theFile, true); }, fail); }, fail); }); }, fail); }); } /* sucht den Downloadlink eines Plans mithilfe eines Links aus der Kursübersicht */ function get_plan(link){ var request = $.ajax({ url: link }); request.done(function gotplan(resulthtml){ var pdf_re = new RegExp('(http://***REMOVED***\\.de/moodle/pluginfile\\.php/\\d+/mod_resource/content/\\d+/.*?\\.pdf)'); var pdflink = pdf_re.exec(resulthtml)[1]; if(pdflink == null){ return 0; } console.log('Plan gefunden: ' + pdflink); download_pdf(pdflink); return 1; }); request.fail(fail); } /* holt die Kursübersicht - bei Verbindungsfehlern wird onfail aufgerufen */ function get_overview(link, onfail){ var request = $.ajax({ url: link }); console.log('Hole Übersicht'); request.done(function gotoverview(resulthtml){ /* ruft get_plan für jeden Link in der Kursübersicht auf */ var plans_re = new RegExp('window\\.open\\('(http://***REMOVED***\\.de/moodle/mod/resource/view\\.php\\?id=\\d+)&redirect=1'\\)', 'g'); var resultarr = resulthtml.match(plans_re); if(resultarr == null){ $('#error_passwd').show('fast'); onfail(); return 0; } var resultl = resultarr.length; while((link = plans_re.exec(resulthtml)) !== null){ console.log('suche Plan ' + link[1]); get_plan(link[1]); } console.log('Übersichts-Request erfolgreich'); return 1; }); request.fail(onfail); } /* such den Link zur Übersicht von der Startseite aus */ function loggedin(resulthtml){ var vertretungs_re = new RegExp('title="Vertretungsplan" href="(http://***REMOVED***\\.de/moodle/course/view\\.php\\?id=\\d+)"'); var link = vertretungs_re.exec(resulthtml)[1]; if(link == null){ return 0; } window.localStorage.setItem('overviewlink', link); console.log('Eingeloggt'); get_overview(link, fail); return 1; } /* sendet einen HTTPost-Request mit Logindaten */ function sendlogin(username, password){ var params = 'username=' + username + '&password=' + password; $('#error_noconn').hide('fast'); $('#error_passwd').hide('fast'); var request = $.ajax({ type: 'POST', url: 'https://***REMOVED***/moodle/login/index.php', data: {username: username, password: password} }); console.log('Logge ein'); request.done(loggedin); request.fail(fail); } /* lädt Benutzerdaten 1) aus den Userinterfaces oder 2) aus dem HTML5 Local Storage */ /* oder 3) gibt null zurück */ function getuserdata(){ var username = encodeURIComponent($('#username').val()); if(username == ''){ username = window.localStorage.getItem('username'); }else{ window.localStorage.setItem('username', username); } var password = encodeURIComponent($('#password').val()); if(password == ''){ password = window.localStorage.getItem('password'); }else{ window.localStorage.setItem('password', password); } console.log('Benutzerdaten geladen'); if(username !== 'undefined' && username != null && username != '' && password !== 'undefined' && password != null && password != ''){ $('#username').val(username); $('#password').val(password); return [username, password]; }else{ return null; } } /* loggt ein oder zeigt Loginform */ function login(){ $.mobile.loading('show', {theme: 'a'}); userdata = getuserdata(); if(userdata){ sendlogin(userdata[0], userdata[1]); $('#loginpopup').popup('close'); return 1; }else{ $('#lnklogin').click(); return 0; } } /* versucht ohne HTTPost die Übersicht zu holen */ /* bei einem Fehlschlag wird in login() versucht, die Nutzerdaten zu laden */ /* und wenn das schiefläuft, muss der Nutzer seine Daten selbst eingeben */ function trylogin(){ var link = window.localStorage.getItem('overviewlink'); $('#loginpopup').popup('close'); if(typeof link !== 'undefined' && link != null){ console.log('Teste Login'); console.log(link); get_overview(link, login); }else{ login(); } } /* gibt aktuelle Pläne aus entries zurück */ function getactual(entries){ var fname_re = new RegExp('.*?(\\d{4})-(\\d{2})-(\\d{2}).*?\\.pdf'); var today = new Date(); var actual = []; today.setHours(0); today.setMinutes(0); today.setSeconds(0); today.setMilliseconds(0); entries.forEach(function(entry){ console.log(entry.name); var results = entry.name.match(fname_re); var fdate = new Date(parseInt(results[1]), parseInt(results[2]) - 1, parseInt(results[3])); if(fdate >= today){ actual.push(entry); } }); return actual; } /* lädt Vertretungspläne aus dem Speicher [1) SD-Karte oder 2) dem internen Speicher] */ function load(){ $.mobile.loading('show', {theme: 'a'}); window.requestFileSystem( LocalFileSystem.PERSISTENT, 0, function(fileSystem){ fileSystem.root.getDirectory('WvSVPlan', {create: true, exclusive: false}, function(dirEntry){ var dirReader = dirEntry.createReader(); dirReader.readEntries( function(entries){ var actual = getactual(entries); console.log('Im Speicher: ' + actual.length + ' Pläne'); if(actual.length > 0){ $('#noplans').hide('slow'); for(j = 0; j < actual.length; j++){ addplanattr(actual[j], false); } }else{ $('#noplans').show('fast'); $('#lnklogin').show('fast'); } }, fail); }, fail); }); }