diff options
author | Simon Rettberg | 2016-04-29 20:55:59 +0200 |
---|---|---|
committer | Simon Rettberg | 2016-04-29 20:55:59 +0200 |
commit | cbd23b7d191327a7cfb6a98e657659045da71af3 (patch) | |
tree | f029ab85c3ac07d3f2a56b4359fd36c265898d6d | |
parent | More Progress; Merged changes from ufpr up to 775cdbd29f5d0f70946d1d5ff09c091... (diff) | |
download | slx-admin-cbd23b7d191327a7cfb6a98e657659045da71af3.tar.gz slx-admin-cbd23b7d191327a7cfb6a98e657659045da71af3.tar.xz slx-admin-cbd23b7d191327a7cfb6a98e657659045da71af3.zip |
Second half of merge....
23 files changed, 474 insertions, 145 deletions
@@ -5,3 +5,4 @@ nbproject/ /config.php /client_config_additional.php +apis/tmpUploads/* diff --git a/apis/statistics.inc.php b/apis/statistics.inc.php new file mode 100644 index 00000000..2be805ba --- /dev/null +++ b/apis/statistics.inc.php @@ -0,0 +1,29 @@ +<?php + +$NOW = time(); +$cutoff = $NOW - 86400*90; + +$res = Database::simpleQuery("SELECT m.machineuuid, m.locationid, m.macaddr, m.clientip, m.lastseen, m.logintime, m.mbram," + . " m.kvmstate, m.cpumodel, m.systemmodel, m.id44mb, m.badsectors, m.hostname, GROUP_CONCAT(s.locationid) AS locs" + . " FROM machine m" + . " LEFT JOIN subnet s ON (INET_ATON(m.clientip) BETWEEN s.startaddr AND s.endaddr)" + . " WHERE m.lastseen > $cutoff" + . " GROUP BY m.machineuuid"); + +$return = array( + 'now' => $NOW, + 'clients' => array(), + 'locations' => Location::getLocationsAssoc() +); +while ($client = $res->fetch(PDO::FETCH_ASSOC)) { + if ($NOW - $client['lastseen'] > 610) { + $client['state'] = 'OFF'; + } elseif ($client['logintime'] == 0) { + $client['state'] = 'IDLE'; + } else { + $client['state'] = 'OCCUPIED'; + } + $return['clients'][] = $client; +} + +die(json_encode($return));
\ No newline at end of file diff --git a/apis/webservice.inc.php b/apis/webservice.inc.php new file mode 100644 index 00000000..42ff674b --- /dev/null +++ b/apis/webservice.inc.php @@ -0,0 +1,34 @@ +<?php +// print results, insert id or affected row count +session_start(); + +if(!isset($_POST['request'])){ + echo json_encode(array( + "errormsg"=>"Request not set, finishing session", + "status" => "error", + "msg" => "")); + session_unset(); + session_destroy(); +}else if($_POST['request']=='logout'){ + echo json_encode(array( + "errormsg"=> "", + "status" => "ok", + "msg" => "Logout successful")); + session_unset(); + session_destroy(); + +}else { + $target_dir = "tmpUploads/"; + $requests = array("login","getinfo","upload","newupload"); + if( in_array($_POST['request'],$requests )) + require("webservice/".$_POST['request'].".php"); + else{ + echo json_encode(array( + "errormsg"=> "Request don't exist, finishing session", + "status" => "error", + "msg" => "")); + session_unset(); + session_destroy(); + } +} +//TODO: analyze session unset/destroy diff --git a/apis/webservice/getinfo.php b/apis/webservice/getinfo.php new file mode 100644 index 00000000..3404008e --- /dev/null +++ b/apis/webservice/getinfo.php @@ -0,0 +1,25 @@ +<?php +if(isset($_SESSION['userid'])){ + $sql = "select user.login, user.fullname, user.email, cities.name from" + ." `user` left join cities on user.city=cities.cityid" + ." where user.userid= :userid"; + + $user=Database::queryFirst($sql, array("userid"=> $_SESSION['userid'])); + $ret = array( + "login"=>$user['login'], + "name"=>$user['fullname'], + "email"=>$user['email'], + "city"=>$user['name'], + "errormsg" => "", + "status" => "ok", + "msg" => "Get informations of user successful" + ); + echo json_encode($ret); + +}else{ + echo json_encode(array( + "errormsg"=> "Not logged in", + "status" => "error", + "msg" => "")); +} + diff --git a/apis/webservice/login.php b/apis/webservice/login.php new file mode 100644 index 00000000..e21975af --- /dev/null +++ b/apis/webservice/login.php @@ -0,0 +1,23 @@ +<?php +$login = $_POST['login']; +$sql = "select * from `user` WHERE login= :login"; +$user=Database::queryFirst($sql, array("login"=> $login)); +if($user){ + if(Crypto::verify($_POST['passwd'],$user['passwd'])){ + $_SESSION['userid']=$user['userid']; + echo json_encode(array( + "errormsg"=> "", + "status" => "ok", + "msg" => "Login successful")); + }else{ + echo json_encode(array( + "errormsg"=> "Wrong passwd", + "status" => "error", + "msg" => "")); + } +}else{ + echo json_encode(array( + "errormsg"=> "User not found", + "status" => "error", + "msg" => "")); +} diff --git a/apis/webservice/newupload.php b/apis/webservice/newupload.php new file mode 100644 index 00000000..b0e683c3 --- /dev/null +++ b/apis/webservice/newupload.php @@ -0,0 +1,67 @@ +<?php +if(!isset($_SESSION['userid'])){ + echo json_encode(array( + "errormsg"=>"Not logged in", + "status" => "error", + "msg" => "")); + die(); +} +if(!isset($_POST['nparts'])){ + echo json_encode(array( + "errormsg"=>"Number of parts isn't set", + "status" => "error", + "msg" => "")); + die(); +} + +function crypto_rand_secure($min, $max){ + $range = $max - $min; + if ($range < 1) return $min; // not so random... + $log = ceil(log($range, 2)); + $bytes = (int) ($log / 8) + 1; // length in bytes + $bits = (int) $log + 1; // length in bits + $filter = (int) (1 << $bits) - 1; // set all lower bits to 1 + do { + $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))); + $rnd = $rnd & $filter; // discard irrelevant bits + } while ($rnd >= $range); + return $min + $rnd; +} + +function getToken($length){ + $token = ""; + $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz"; + $codeAlphabet.= "0123456789"; + $max = strlen($codeAlphabet) - 1; + for ($i=0; $i < $length; $i++) { + $token .= $codeAlphabet[crypto_rand_secure(0, $max)]; + } + return $token; +} +$token=getToken(35); +while(Database::queryFirst("select * from upload where `token`=:token", array( + "token" => $token))){ + $token = getToken(35); +} +$okay=Database::exec("INSERT INTO upload(`userid`, `nparts`, `nremaining`, `token`)". + " values (:userid, :nparts, :nremaining, :token)", array( + "userid"=>$_SESSION['userid'], + "nparts"=>$_POST['nparts'], + "nremaining"=>$_POST['nparts'], + "token"=> $token + )); +if($okay){ + echo json_encode(array( + "uploadid"=>$token, + "errormsg"=>"", + "status" => "ok", + "msg" => "New upload succesful")); + mkdir($target_dir.$token."/",0755, true); +}else{ + echo json_encode(array( + "errormsg"=>"Error when saving new upload, please retry", + "status" => "error", + "msg" => "")); +} + diff --git a/apis/webservice/upload.php b/apis/webservice/upload.php new file mode 100644 index 00000000..50ada40e --- /dev/null +++ b/apis/webservice/upload.php @@ -0,0 +1,62 @@ +<?php +if(!isset($_POST['uploadid'])){ + echo json_encode(array( + "errormsg"=>"Not logged in", + "status" => "error", + "msg" => "")); + die(); +}elseif (!isset($_FILES['fileToUpload'])){ + echo json_encode(array( + "errormsg"=>"No file received", + "status" => "error", + "msg" => "")); + die(); +} + +$upload = Database::queryFirst("Select * from upload where token = :token", + array( "token" => $_POST['uploadid'])); +if($upload['userid']!= $_SESSION['userid']){ + echo json_encode(array( + "errormsg"=>"Not same owner", + "status" => "error", + "msg" => "")); + die(); +} + +$name = $_FILES["fileToUpload"]["name"]; +$upload['nremaining'] = $upload['nremaining'] - 1; +if ($upload['nremaining'] < 0){ + echo json_encode(array( + "errormsg"=>"Already received all the parts", + "status" => "error", + "msg" => "")); + die(); +} +$target_file = $target_dir.$_POST['uploadid']."/".$name; +if(move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)){ + $ret = Database::exec("UPDATE upload SET nremaining= :nremaining". + " WHERE id=:id", array( + "id"=>$upload['id'], + "nremaining"=>$upload['nremaining'] + )); + if ($upload['nremaining'] == 0) { + echo json_encode(array( + "errormsg"=>"", + "status" => "ok", + "msg" => "Upload successful, sending to taskmanager")); + //passa pro taskmanager; + die(); + }else{ + echo json_encode(array( + "errormsg"=>"", + "status" => "ok", + "msg" => "Upload successful, waiting next part")); + die(); + } +} else { + echo json_encode(array( + "errormsg"=>"", + "status" => "error", + "msg" => "Error on upload, please resend")); +} + diff --git a/modules/backup/lang/de/module.json b/modules/backup/lang/de/module.json index 5e3efea2..a0dbdf27 100644 --- a/modules/backup/lang/de/module.json +++ b/modules/backup/lang/de/module.json @@ -1,14 +1,4 @@ { - "lang_backup": "Sichern", - "lang_backupDescription": "Hier k\u00f6nnen Sie die Konfiguration des Satellitenservers sichern. Dies beinhaltet die Datenbank \u00fcber alle Virtuellen Maschinen, Veranstaltungen, Authentifizerungsmodule, Passw\u00f6rter, Proxies, den konfigurierten VM-Store sowie weitere Konfiguration des MiniLinux.\r\nDie Festplattenabbilder der Virtuellen Maschinen auf dem VM-Store werden hierbei nicht gesichert. Eventuelle Backups des Stores m\u00fcssen separat durchgef\u00fchrt werden.", - "lang_backupRestore": "Sichern und Wiederherstellen", - "lang_browseForFile": "Durchsuchen", - "lang_download": "Herunterladen", - "lang_dozmodExplanation": "Die Datenbank des Dozentenmoduls wiederherstellen. Dazu geh\u00f6ren die Metadaten der Virtuellen Maschinen, die Veranstaltungen, etc. Bitte beachten Sie, dass hierzu auf dem konfigurierten VM-Store die passenden VM-Abbilder vorliegen m\u00fcssen, da diese extern gespeichert werden. Wenn sich der Servername oder die -adresse ge\u00e4ndert haben stellen Sie bitte sicher, dass die relativen Pfade innerhalb des Netzlaufwerks gleich geblieben sind. Ansonsten werden die wiederhergestellten VMs nicht verwendbar sein.", - "lang_restore": "Hochladen", - "lang_restoreDescription": "Hier k\u00f6nnen Sie ein Backup der Konfiguration wieder einspielen. Bitte beachten Sie, dass der Server dabei neu gestartet wird, daher sollten Sie dies m\u00f6glichst durchf\u00fchren, wenn das System nicht genutzt wird, und keine Dozenten Veranstaltungen oder Virtuelle Labore erstellen oder hoch-\/herunterladen. Bitte beachten Sie, dass dabei auch das urspr\u00fcngliche Passwort der Weboberfl\u00e4che wiederhergestellt wird.", - "lang_restoreDozmodConfig": "Dozentenmodul-Konfiguration wiederherstellen", - "lang_restoreSystemConfig": "Systemkonfiguration wiederherstellen", - "lang_selectFile": "Bitte w\u00e4hlen Sie ein Backup-Archiv", - "lang_systemExplanation": "Die Grundkonfiguration des Satelliten wiederherstellen: Authentifizierungmethode, Passw\u00f6rter, Proxies, VM-Storage, etc.\r\nACHTUNG: Wenn Sie ein Backup von vor WS15\/16 einspielen (Backup-Format vor Version 10), wird die Systemkonfiguration in jedem Fall wiederhergestellt, auch wenn Sie diesen Haken nicht setzen." -}
\ No newline at end of file + "module_name": "Sichern/Wiederherstellen", + "page_title": "Sichern und wiederherstellen" +} diff --git a/modules/imgmanagement/page.inc.php b/modules/imgmanagement/page.inc.php index 27844e23..dc19cb2a 100644 --- a/modules/imgmanagement/page.inc.php +++ b/modules/imgmanagement/page.inc.php @@ -16,11 +16,6 @@ class Page_Imgmanagement extends Page Util::redirect('?do=Main'); } - - //Depends on the server location; - $this->baselocation = '/var/images/'; - $this->images = array(); - error_reporting(E_ALL); ini_set('display_errors','on'); @@ -29,46 +24,38 @@ class Page_Imgmanagement extends Page } protected function doRender() - { - /*get city of user !!!!NOT TESTED!!!! - - $data=array( 'id'= User.getId()); - $res = Database::exec("SELECT cityid FROM user WHERE userid=:id",$data); - $cityid = $res->fetch(PDO::FETCH_ASSOC); - $res = Database::exec("SELECT name FROM cities WHERE cityid=:cityid",$cityid); - $city = $res->fetch(PDO::FETCH_ASSOC); - $location = $baselocation . $city; - - - verify type of vars (string concatenation and more) - !!!!NOT TESTED!!!! - */ - - error_reporting(E_ALL); + { + error_reporting(E_ALL); ini_set('display_errors','on'); - //Search images on location specified - $location = $this->baselocation . 'curitiba/*'; - //Gets the configuration of each image - $config = substr($location,0,-1).'config.json'; - $imgsactive = json_decode(file_get_contents($config),true); - $images = glob($location, GLOB_ONLYDIR); - $actives = array(); - $deactives= array(); - foreach($images as &$imgname){ - $imgname= substr($imgname, strlen($location)-1); - //fill associative array (img->active[true/false]) - $this->images[$imgname] = isset($imgsactive[$imgname])?$imgsactive[$imgname] : false; - if($this->images[$imgname]){ - array_push($actives, array('name' => $imgname)); - }else{ - array_push($deactives, array('name'=>$imgname)); - } - } - - //Save eventually new images to config.json - $fp = fopen($config,'w'); - fwrite($fp,json_encode($this->images)); - fclose($fp); + + $actives = array(); + $deactives = array(); + + $res = Database::simpleQuery("SELECT id, name, path, userid, is_template, is_active, description FROM images ORDER BY id DESC"); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if($row['is_active']) + $actives[] = array( + 'id' => $row['id'], + 'name' => $row['name'], + 'path' => $row['path'], + 'userid' => $row['userid'], + 'is_template' => $row['is_template'], + 'is_active' => $row['is_active'], + 'description' => $row['description'] + ); + else + $deactives[] = array( + 'id' => $row['id'], + 'name' => $row['name'], + 'path' => $row['path'], + 'userid' => $row['userid'], + 'is_template' => $row['is_template'], + 'is_active' => $row['is_active'], + 'description' => $row['description'] + ); + + } + Render::addTemplate('page-imgmanagement', array( 'deactives' => $deactives, 'actives' => $actives)); diff --git a/modules/imgmanagement/templates/page-imgmanagement.html b/modules/imgmanagement/templates/page-imgmanagement.html index 795ae39f..cdae627b 100644 --- a/modules/imgmanagement/templates/page-imgmanagement.html +++ b/modules/imgmanagement/templates/page-imgmanagement.html @@ -29,8 +29,13 @@ </div> </div> - <a class="btn btn-default" href="#" role="button">Upload de Nova Imagem<a> - <a class="btn btn-info" href="#" role="button">Gerar IPXE<a> + <div class="panel-body text-center"> + <input type='button' value='<<' id='move_left' /> + <input type='button' value='>>' id='move_right' /> + <a class="btn btn-default" href="#" role="button">Upload de Nova Imagem<a> + <a class="btn btn-info" href="#" role="button">Gerar IPXE<a> + <a class="btn btn-info" href="#" role="button">Salvar<a> + </div> </div> </div> @@ -43,4 +48,15 @@ }); }); + $('body').on('click', 'li', function() { + $(this).toggleClass('selected'); + }); + + $('#move_left').click(function() { + $('.source').append($('.target .selected').removeClass('selected')); + }); + + $('#move_right').click(function() { + $('.target').append($('.source .selected').removeClass('selected')); + }); </script> diff --git a/modules/main/lang/de/module.json b/modules/main/lang/de/module.json new file mode 100644 index 00000000..f03e52ad --- /dev/null +++ b/modules/main/lang/de/module.json @@ -0,0 +1,4 @@ +{ + "module_name": "Dashboard", + "page_title": "Startseite" +} diff --git a/modules/main/lang/de/templates/main-menu.json b/modules/main/lang/de/templates/main-menu.json index 67ae974a..057bfcf2 100644 --- a/modules/main/lang/de/templates/main-menu.json +++ b/modules/main/lang/de/templates/main-menu.json @@ -1,8 +1,4 @@ { - "lang_backup": "Backup\/Restore", - "lang_client": "Client", - "lang_clientLog": "Client Log", - "lang_clientStats": "Client-Statistiken", "lang_configurationBasic": "PXE\/Boot", "lang_configurationVariables": "KonfigurationsVariablen", "lang_dozmod": "Dozentenmodul", @@ -23,4 +19,4 @@ "lang_vmLocation": "VM Speicherort", "lang_warning": "Warnung", "lang_webInterface": "Web-Schnittstelle" -}
\ No newline at end of file +} diff --git a/modules/serversetup/lang/pt/templates/ipxe-adv.json b/modules/serversetup/lang/pt/templates/ipxe-adv.json new file mode 100644 index 00000000..19d120ad --- /dev/null +++ b/modules/serversetup/lang/pt/templates/ipxe-adv.json @@ -0,0 +1,28 @@ +{ + "lang_bootBehavior": "Comportamento Padr\u00e3o de Boot", + "lang_bootInfo": "Aqui ajustes podem ser feitos na apar\u00eancia do menu de boot.", + "lang_bootMenu": "Menu de Boot", + "lang_bootMenuCreate": "Criar Menu de Boot", + "lang_cancel": "Cancelar", + "lang_close": "Fechar", + "lang_compile": "Compilar", + "lang_compilingIpxe": "Compilando iPXE", + "lang_customScript": "Script Customizado", + "lang_download": "Baixar", + "lang_example": "Exemplo", + "lang_extension": "Extens\u00e3o", + "lang_ipxeInfo": "Aqui \u00e9 poss\u00edvel compilar e baixar o iPXE utilizando um script customiz\u00e1vel.", + "lang_ipxeWarning": "Se esta for a primeira vez compilando, poder\u00e1 levar entre 1 e 4 minutos para que termine.", + "lang_loading": "Carregando", + "lang_localHDD": "HDD Local", + "lang_menuCustom": "Menu Adicional Customizado", + "lang_menuCustomHint1": "Aqui voc\u00ea tem a oportunidade de adicionar seu pr\u00f3prio c\u00f3digo de menu para o menu PXE exibido, por exemplo, para se referir a outro servidor PXE. O formato corresponde ao formato de menu syslinux.", + "lang_menuCustomHint2": "Voc\u00ea pode criar uma ou mais entradas. Se voc\u00ea quiser criar uma entrada que \u00e9 iniciada automaticamente quando o usu\u00e1rio faz uma sele\u00e7\u00e3o, atribua como", + "lang_menuCustomHint3": "e selecione como o comportamento de boot padr\u00e3o tamb\u00e9m my-entry.", + "lang_menuDisplayTime": "Tempo de Exibi\u00e7\u00e3o do Menu", + "lang_mountIpxe": "Montar iPXE", + "lang_restoreDefault": "Restaurar Padr\u00e3o", + "lang_saveScript": "Salvar Script", + "lang_seconds": "Segundos", + "lang_success": "Arquivo criado com sucesso:" +} diff --git a/modules/serversetup/page.inc.php b/modules/serversetup/page.inc.php index e37d7d40..289bf3d5 100644 --- a/modules/serversetup/page.inc.php +++ b/modules/serversetup/page.inc.php @@ -65,19 +65,27 @@ class Page_ServerSetup extends Page Render::addTemplate('ipxe_update', array('taskid' => $taskid)); } - Render::addTemplate('ipaddress', array( - 'ips' => $this->taskStatus['data']['addresses'] - )); - $data = $this->currentMenu; - if (!isset($data['defaultentry'])) - $data['defaultentry'] = 'net'; - if ($data['defaultentry'] === 'net') - $data['active-net'] = 'checked'; - if ($data['defaultentry'] === 'hdd') - $data['active-hdd'] = 'checked'; - if ($data['defaultentry'] === 'custom') - $data['active-custom'] = 'checked'; - Render::addTemplate('ipxe', $data); + if (Request::get('advanced', 'false', 'string') === 'false') { + Render::addTemplate('ipxe-smp'); + } else { + Render::addTemplate('ipaddress', array( + 'ips' => $this->taskStatus['data']['addresses'] + )); + $data = $this->currentMenu; + if (!isset($data['defaultentry'])) + $data['defaultentry'] = 'net'; + if ($data['defaultentry'] === 'net') + $data['active-net'] = 'checked'; + if ($data['defaultentry'] === 'hdd') + $data['active-hdd'] = 'checked'; + if ($data['defaultentry'] === 'custom') + $data['active-custom'] = 'checked'; + //There is no $this->username and no pxe.embed, why do we need this? + //Page won't load with lines below uncommented + //$data['username'] = $this->username; + //$data['script'] = file_get_contents("/opt/taskmanager/data/pxe.embed"); + Render::addTemplate('ipxe-adv', $data); + } } // ----------------------------------------------------------------------------------------------- diff --git a/modules/serversetup/templates/ipaddress.html b/modules/serversetup/templates/ipaddress.html index e4967703..e4c1fba9 100644 --- a/modules/serversetup/templates/ipaddress.html +++ b/modules/serversetup/templates/ipaddress.html @@ -1,3 +1,4 @@ +<a class="btn btn-default" href="?do=Serversetup&advanced=false" role="button"><strong>{{lang_ipxeSmp}}</strong></a></br></br> <div class="panel panel-default"> <div class="panel-heading"> {{lang_bootAddress}} @@ -31,4 +32,4 @@ </p> </form> </div> -</div>
\ No newline at end of file +</div> diff --git a/modules/serversetup/templates/ipxe.html b/modules/serversetup/templates/ipxe-adv.html index 54d7db16..00e9fd3a 100644 --- a/modules/serversetup/templates/ipxe.html +++ b/modules/serversetup/templates/ipxe-adv.html @@ -1,7 +1,7 @@ <div class="panel panel-default"> <div class="panel-heading"> {{lang_mountIpxe}} - </div> + </div> <div class="panel-body"> <p>{{lang_ipxeInfo}}</p> <label for="ext">{{lang_extension}}:</label> diff --git a/modules/serversetup/templates/ipxe-smp.html b/modules/serversetup/templates/ipxe-smp.html new file mode 100644 index 00000000..d126710c --- /dev/null +++ b/modules/serversetup/templates/ipxe-smp.html @@ -0,0 +1,62 @@ +<a class="btn btn-default" href="?do=Serversetup&advanced=true" role="button"><strong>{{lang_ipxeAdv}}</strong></a></br></br> +<div class="panel panel-default"> + <div class="panel-heading"> + {{lang_mountIpxe}} + </div> + <div class="panel-body"> + <p>{{lang_ipxeSmpInfo}}</p> + <button id="mount-button" onclick="mountIpxe('iso');" class="btn btn-primary" type="button" data-toggle="modal" data-target="#ipxe-modal" data-backdrop="static"> {{lang_compileIso}} + </button> + <button id="mount-button" onclick="mountIpxe('usb');" class="btn btn-primary" type="button" data-toggle="modal" data-target="#ipxe-modal" data-backdrop="static"> {{lang_compileUsb}} + </button> + <br> + </div> +</div> + + +<div class="modal fade" id="ipxe-modal" tabindex="-1" role="dialog" aria-labelledby="ipxe-modal-label" aria-hidden="true"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="ipxe-modal-label">{{lang_compilingIpxe}}</h4> + </div> + <div class="modal-body" id="ipxe-modal-body"> + + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button> + <button id="download-btn" type="button" class="btn btn-primary" disabled="disabled" onclick="downloadIpxe()">{{lang_download}}</button> + </div> + </div> + </div> +</div> + +<script> + function mountIpxe(extension) { + document.getElementById('ipxe-modal-body').innerHTML = "<div class='alert alert-info' role='alert'>{{lang_ipxeWarning}}</div>" + + "{{lang_loading}} <img src='fonts/loader.gif'/>"; + $("#download-btn").prop("disabled",true); + var xmlhttp = new XMLHttpRequest(); + xmlhttp.open("GET","?do=ServerSetup&async=true&submitTask=true&extension=" + extension,true); + xmlhttp.onreadystatechange= function() { + if (xmlhttp.readyState==4 && xmlhttp.status==200) { + var initResponse = xmlhttp.responseText; + if(initResponse != "success") + document.getElementById('ipxe-modal-body').innerHTML = initResponse; + else { + document.getElementById('ipxe-modal-body').innerHTML = "{{lang_success}}: ipxe." + extension; + document.getElementById('download-btn').setAttribute('onclick','downloadIpxe(\''+extension+'\')'); + $("#download-btn").prop("disabled",false); + } + } + } + xmlhttp.send(); + } + + function downloadIpxe(extension) { + console.log("TESTE"); + console.log(extension); + window.location = "?do=ServerSetup&download=" + extension; + } +</script> diff --git a/modules/statistics/lang/de/module.json b/modules/statistics/lang/de/module.json new file mode 100644 index 00000000..35a62cce --- /dev/null +++ b/modules/statistics/lang/de/module.json @@ -0,0 +1,4 @@ +{ + "module_name": "Client-Statistiken", + "page_title": "Client-Statistiken" +} diff --git a/modules/support/faq.json b/modules/support/faq.json new file mode 100644 index 00000000..1c1d372f --- /dev/null +++ b/modules/support/faq.json @@ -0,0 +1,19 @@ +{ + "faq": [ + {"question": "Este é o FAQ", + "answer": "Ao clicar em cada uma pergunta, elas se expandem exibindo as respostas!", + "order": "One", + "highlight": true + }, + {"question": "Por enquanto não há nada por aqui (ツ)_/¯ ", + "answer": "As perguntas serão adicionadas conforme as dúvidas forem surgindo", + "order": "Two", + "highlight": true + }, + {"question": "Nem todas as perguntas estarão aqui", + "answer": "Se tiver uma dúvida que não está no FAQ, envie um e-mail clicando no botão abaixo ;)", + "order": "Three", + "highlight": false + } + ] +} diff --git a/modules/support/page.inc.php b/modules/support/page.inc.php index d4012c1a..10695969 100644 --- a/modules/support/page.inc.php +++ b/modules/support/page.inc.php @@ -65,10 +65,16 @@ class Page_Support extends Page protected function doRender(){ error_reporting(E_ALL); ini_set('display_errors','on'); - if (strpos($_SERVER['REQUEST_URI'], "true") !== false) - Render::addTemplate('page-faq'); - else - Render::addTemplate('page-support'); + if (strpos($_SERVER['REQUEST_URI'], "true") !== false){ + Render::addTemplate('page-faq', + json_decode(file_get_contents("modules/support/faq.json"),true) + ); + } + else{ + Render::addTemplate('page-support', + json_decode(file_get_contents("modules/support/faq.json"),true) + ); + } // Render::addTemplate('page-support', array( // 'token' => Session:get('token')); } diff --git a/modules/support/templates/page-faq.html b/modules/support/templates/page-faq.html index ec9fe832..ae706f4b 100644 --- a/modules/support/templates/page-faq.html +++ b/modules/support/templates/page-faq.html @@ -5,54 +5,25 @@ <!-- //FAQ --> <div class="panel-body" id="accordion" role="tablist" aria-multiselectable="true"> - <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingOne"> + {{#faq}} + <div class="panel panel-default"> + <div class="panel-heading" role="tab" id="heading{{order}}"> <h4 class="panel-title"> - <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"> - {{lang_faq#1}} + <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{order}}" aria-expanded="false" aria-controls="collapse{{order}}"> + {{question}} </a> </h4> </div> - <div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne"> + <div id="collapse{{order}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{order}}"> <div class="panel-body"> - {{lang_content#1}} + {{answer}} </div> - </div> - </div> - - <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingTwo"> - <h4 class="panel-title"> - <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"> - {{lang_faq#2}} - </a> - </h4> - </div> - <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo"> - <div class="panel-body"> - {{lang_content#2}} - </div> - </div> - </div> - - <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingThree"> - <h4 class="panel-title"> - <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree"> - {{lang_faq#3}} - </a> - </h4> - </div> - <div id="collapseThree" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree"> - <div class="panel-body"> - {{lang_content#3}} - </div> - </div> - </div> + </div> + </div> + {{/faq}} <a class="btn btn-default" href="?do=Support&showfaq=false" role="button"><strong>{{lang_supIntro}}</strong></a> - </div> -</div> + </div></div> </div> diff --git a/modules/support/templates/page-support.html b/modules/support/templates/page-support.html index 231cbc1b..196e0891 100644 --- a/modules/support/templates/page-support.html +++ b/modules/support/templates/page-support.html @@ -5,34 +5,26 @@ </div> <!-- //FAQ --> <div class="panel-body" id="accordion" role="tablist" aria-multiselectable="true"> - <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingOne"> + + {{#faq}} + {{#highlight}} + <div class="panel panel-default"> + <div class="panel-heading" role="tab" id="heading{{order}}"> <h4 class="panel-title"> - <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"> - {{lang_faq#1}} + <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{order}}" aria-expanded="false" aria-controls="collapse{{order}}"> + {{question}} </a> </h4> </div> - <div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne"> + <div id="collapse{{order}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{order}}"> <div class="panel-body"> - {{lang_content#1}} + {{answer}} </div> - </div> - </div> - <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingTwo"> - <h4 class="panel-title"> - <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"> - {{lang_faq#2}} - </a> - </h4> - </div> - <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo"> - <div class="panel-body"> - {{lang_content#2}} - </div> - </div> - </div> + </div> + </div> + {{/highlight}} + {{/faq}} + <a class="btn btn-default" href="?do=Support&showfaq=true" role="button"><strong>{{lang_showall}}</strong></a> </div> </div> diff --git a/modules/syslog/lang/de/module.json b/modules/syslog/lang/de/module.json new file mode 100644 index 00000000..b9e8de49 --- /dev/null +++ b/modules/syslog/lang/de/module.json @@ -0,0 +1,4 @@ +{ + "module_name": "Client-Log", + "page_title": "Lognachrichten gebooteter Clients" +} |