From dbc0d9614421e064cc62aacf116ebb783c83f2f3 Mon Sep 17 00:00:00 2001 From: Jonathan Bauer Date: Fri, 1 Apr 2016 16:50:13 +0200 Subject: [merge] merging c3sl / fr - initial commit --- TODO | 5 + fonts/loader.gif | Bin 0 -> 673 bytes inc/configmodule/adauth.inc.php | 3 +- inc/configmodule/ldapauth.inc.php | 3 +- inc/dictionary.inc.php | 20 +- inc/event.inc.php | 19 +- inc/message.inc.php | 6 +- inc/paginate.inc.php | 2 +- inc/render.inc.php | 86 +- inc/taskmanagercallback.inc.php | 7 - inc/trigger.inc.php | 1 + inc/user.inc.php | 23 + index.php | 13 +- lang/de/messages-hardcoded.json | 3 + lang/de/modules/adduser.json | 8 + lang/de/modules/backup.json | 14 + lang/de/templates/baseconfig/_page.json | 10 +- lang/de/templates/page-news.json | 1 + lang/de/templates/serversetup/ipxe.json | 1 + lang/de/templates/sysconfig/ad_ldap-homedir.json | 19 - lang/en/messages-hardcoded.json | 38 +- lang/en/modules/backup/_page.json | 14 + lang/en/modules/backup/restore.json | 8 + lang/en/modules/baseconfig/_page.json | 7 + lang/en/modules/citymanagement.json | 13 + lang/en/modules/dozmod/images-delete.json | 12 + lang/en/modules/dozmod/mailconfig.json | 21 + lang/en/modules/dozmod/orglist.json | 6 + lang/en/modules/dozmod/userlist.json | 12 + lang/en/modules/eventlog/_page.json | 6 + lang/en/modules/internetaccess/_page.json | 14 + lang/en/modules/internetaccess/restart.json | 5 + lang/en/modules/locations/location-subnets.json | 18 + lang/en/modules/locations/locations.json | 10 + lang/en/modules/locations/subnets.json | 7 + lang/en/modules/main.json | 33 + lang/en/modules/main/dialog-generic.json | 3 + lang/en/modules/main/main-menu.json | 26 + lang/en/modules/main/messagebox-warning.json | 2 + lang/en/modules/main/page-main-guest.json | 7 + lang/en/modules/main/page-main.json | 11 + lang/en/modules/messagebox-error.json | 3 + lang/en/modules/messagebox-info.json | 2 + lang/en/modules/messagebox-success.json | 2 + lang/en/modules/minilinux/download.json | 2 + lang/en/modules/minilinux/filelist.json | 12 + lang/en/modules/news/page-news.json | 12 + lang/en/modules/page-adduser.json | 8 + lang/en/modules/page-minilinux.json | 4 + lang/en/modules/pagenav.json | 2 + lang/en/modules/serversetup/ipaddress.json | 7 + lang/en/modules/serversetup/ipxe.json | 31 + lang/en/modules/serversetup/ipxe_update.json | 4 + lang/en/modules/session/page-login.json | 8 + lang/en/modules/statistics/clientlist.json | 14 + lang/en/modules/statistics/cpumodels.json | 6 + lang/en/modules/statistics/id44.json | 5 + lang/en/modules/statistics/kvmstate.json | 5 + lang/en/modules/statistics/machine-hdds.json | 13 + lang/en/modules/statistics/machine-main.json | 26 + lang/en/modules/statistics/machine-notes.json | 4 + lang/en/modules/statistics/machine-usage.json | 4 + lang/en/modules/statistics/memory.json | 5 + lang/en/modules/statistics/newclients.json | 4 + lang/en/modules/statistics/summary.json | 6 + lang/en/modules/statistics/syslog.json | 7 + lang/en/modules/sysconfig/_page.json | 28 + lang/en/modules/sysconfig/ad-finish.json | 7 + lang/en/modules/sysconfig/ad-selfsearch.json | 10 + lang/en/modules/sysconfig/ad-start.json | 23 + .../modules/sysconfig/ad_ldap-checkconnection.json | 8 + .../sysconfig/ad_ldap-checkcredentials.json | 6 + lang/en/modules/sysconfig/ad_ldap-homedir.json | 18 + lang/en/modules/sysconfig/branding-check.json | 5 + lang/en/modules/sysconfig/branding-start.json | 9 + lang/en/modules/sysconfig/cfg-finish.json | 4 + lang/en/modules/sysconfig/cfg-start.json | 6 + lang/en/modules/sysconfig/config-module-list.json | 4 + lang/en/modules/sysconfig/custom-filelist.json | 3 + lang/en/modules/sysconfig/custom-fileselect.json | 5 + lang/en/modules/sysconfig/custom-upload.json | 8 + .../en/modules/sysconfig/ldap-checkconnection.json | 5 + .../modules/sysconfig/ldap-checkcredentials.json | 6 + lang/en/modules/sysconfig/ldap-finish.json | 6 + lang/en/modules/sysconfig/ldap-start.json | 16 + lang/en/modules/sysconfig/sshconfig-start.json | 10 + lang/en/modules/sysconfig/start.json | 4 + lang/en/modules/syslog/page-syslog.json | 10 + lang/en/modules/systemstatus/_page.json | 11 + lang/en/modules/systemstatus/addresses.json | 2 + lang/en/modules/systemstatus/diskstat.json | 12 + lang/en/modules/systemstatus/services.json | 2 + lang/en/modules/systemstatus/systeminfo.json | 15 + lang/en/modules/translation/_page.json | 9 + lang/en/modules/translation/edit.json | 12 + lang/en/modules/translation/template-list.json | 5 + .../en/modules/usermanagement/user-management.json | 18 + lang/en/modules/vmstore/mount.json | 5 + lang/en/modules/vmstore/page-vmstore.json | 17 + lang/en/modules/webinterface/httpd-restart.json | 4 + lang/en/modules/webinterface/https.json | 12 + lang/en/modules/webinterface/passwords.json | 7 + lang/en/templates/backup/_page.json | 14 - lang/en/templates/backup/restore.json | 8 - lang/en/templates/baseconfig/_page.json | 7 - lang/en/templates/dialog-generic.json | 3 - lang/en/templates/dozmod/images-delete.json | 12 - lang/en/templates/dozmod/mailconfig.json | 21 - lang/en/templates/dozmod/orglist.json | 6 - lang/en/templates/dozmod/userlist.json | 12 - lang/en/templates/eventlog/_page.json | 6 - lang/en/templates/internetaccess/_page.json | 14 - lang/en/templates/internetaccess/restart.json | 5 - lang/en/templates/locations/location-subnets.json | 18 - lang/en/templates/locations/locations.json | 10 - lang/en/templates/locations/subnets.json | 7 - lang/en/templates/main-menu.json | 26 - lang/en/templates/messagebox-error.json | 3 - lang/en/templates/messagebox-info.json | 2 - lang/en/templates/messagebox-success.json | 2 - lang/en/templates/messagebox-warning.json | 2 - lang/en/templates/minilinux/download.json | 2 - lang/en/templates/minilinux/filelist.json | 12 - lang/en/templates/page-adduser.json | 8 - lang/en/templates/page-login.json | 8 - lang/en/templates/page-main-guest.json | 7 - lang/en/templates/page-main.json | 11 - lang/en/templates/page-minilinux.json | 4 - lang/en/templates/page-news.json | 12 - lang/en/templates/page-syslog.json | 10 - lang/en/templates/page-vmstore.json | 17 - lang/en/templates/pagenav.json | 2 - lang/en/templates/serversetup/ipaddress.json | 7 - lang/en/templates/serversetup/ipxe.json | 18 - lang/en/templates/serversetup/ipxe_update.json | 4 - lang/en/templates/statistics/clientlist.json | 14 - lang/en/templates/statistics/cpumodels.json | 6 - lang/en/templates/statistics/id44.json | 5 - lang/en/templates/statistics/kvmstate.json | 5 - lang/en/templates/statistics/machine-hdds.json | 13 - lang/en/templates/statistics/machine-main.json | 26 - lang/en/templates/statistics/machine-notes.json | 4 - lang/en/templates/statistics/machine-usage.json | 4 - lang/en/templates/statistics/memory.json | 5 - lang/en/templates/statistics/newclients.json | 4 - lang/en/templates/statistics/summary.json | 6 - lang/en/templates/statistics/syslog.json | 7 - lang/en/templates/sysconfig/_page.json | 28 - lang/en/templates/sysconfig/ad-finish.json | 7 - lang/en/templates/sysconfig/ad-selfsearch.json | 10 - lang/en/templates/sysconfig/ad-start.json | 23 - .../sysconfig/ad_ldap-checkconnection.json | 8 - .../sysconfig/ad_ldap-checkcredentials.json | 6 - lang/en/templates/sysconfig/ad_ldap-homedir.json | 19 - lang/en/templates/sysconfig/branding-check.json | 5 - lang/en/templates/sysconfig/branding-start.json | 9 - lang/en/templates/sysconfig/cfg-finish.json | 4 - lang/en/templates/sysconfig/cfg-start.json | 7 - .../en/templates/sysconfig/config-module-list.json | 4 - lang/en/templates/sysconfig/custom-filelist.json | 3 - lang/en/templates/sysconfig/custom-fileselect.json | 5 - lang/en/templates/sysconfig/custom-upload.json | 8 - .../templates/sysconfig/ldap-checkconnection.json | 5 - .../templates/sysconfig/ldap-checkcredentials.json | 6 - lang/en/templates/sysconfig/ldap-finish.json | 6 - lang/en/templates/sysconfig/ldap-start.json | 16 - lang/en/templates/sysconfig/sshconfig-start.json | 10 - lang/en/templates/sysconfig/start.json | 4 - lang/en/templates/systemstatus/_page.json | 11 - lang/en/templates/systemstatus/addresses.json | 2 - lang/en/templates/systemstatus/diskstat.json | 12 - lang/en/templates/systemstatus/services.json | 2 - lang/en/templates/systemstatus/systeminfo.json | 15 - lang/en/templates/translation/_page.json | 9 - lang/en/templates/translation/edit.json | 12 - lang/en/templates/translation/template-list.json | 5 - lang/en/templates/vmstore/mount.json | 5 - lang/en/templates/webinterface/httpd-restart.json | 4 - lang/en/templates/webinterface/https.json | 12 - lang/en/templates/webinterface/passwords.json | 7 - lang/pt/templates/sysconfig/ad_ldap-homedir.json | 3 - modules/adduser.inc.php | 60 - modules/adduser/config.json | 4 + modules/adduser/module.inc.php | 60 + modules/adduser/templates/page-adduser.html | 28 + modules/backup.inc.php | 134 - modules/backup/config.json | 4 + modules/backup/module.inc.php | 164 + modules/backup/templates/_page.html | 41 + modules/backup/templates/restore.html | 62 + modules/baseconfig.inc.php | 127 - modules/baseconfig/config.json | 4 + modules/baseconfig/module.inc.php | 127 + modules/baseconfig/templates/_page.html | 186 + modules/citymanagement/config.json | 5 + modules/citymanagement/module.inc.php | 81 + .../templates/page-citymanagement.html | 77 + modules/dozmod.inc.php | 252 - modules/dozmod/config.json | 4 + modules/dozmod/module.inc.php | 252 + modules/dozmod/templates/images-delete.html | 57 + modules/dozmod/templates/mailconfig.html | 91 + modules/dozmod/templates/orglist.html | 51 + modules/dozmod/templates/userlist.html | 62 + modules/eventlog.inc.php | 70 - modules/eventlog/config.json | 4 + modules/eventlog/module.inc.php | 70 + modules/eventlog/templates/_page.html | 41 + modules/imgmanagement/config.json | 5 + modules/imgmanagement/module.inc.php | 76 + .../templates/page-imgmanagement.html | 46 + modules/internetaccess.inc.php | 51 - modules/internetaccess/config.json | 4 + modules/internetaccess/module.inc.php | 51 + modules/internetaccess/templates/_page.html | 40 + modules/internetaccess/templates/restart.html | 22 + modules/locations.inc.php | 348 - modules/locations/config.json | 4 + modules/locations/module.inc.php | 348 + modules/locations/templates/location-subnets.html | 73 + modules/locations/templates/locations.html | 96 + modules/locations/templates/subnets.html | 35 + modules/main.inc.php | 54 - modules/main/config.json | 4 + modules/main/module.inc.php | 64 + modules/main/templates/dialog-generic.html | 13 + modules/main/templates/footer.html | 2 + modules/main/templates/main-menu.html | 51 + modules/main/templates/main-menu.html.topnavbar | 92 + modules/main/templates/messagebox-error.html | 1 + modules/main/templates/messagebox-info.html | 1 + modules/main/templates/messagebox-success.html | 1 + modules/main/templates/messagebox-warning.html | 1 + modules/main/templates/page-login.html | 11 + modules/main/templates/page-main-guest.html | 15 + modules/main/templates/page-main.html | 36 + modules/main/templates/page-minilinux.html | 14 + modules/main/templates/page-news.html | 57 + modules/main/templates/page-syslog.html | 58 + modules/main/templates/page-vmstore.html | 111 + modules/main/templates/pagenav.html | 16 + modules/main/templates/tm-callback-trigger.html | 15 + modules/minilinux.inc.php | 128 - modules/minilinux/config.json | 4 + modules/minilinux/module.inc.php | 128 + modules/minilinux/templates/download.html | 1 + modules/minilinux/templates/filelist.html | 77 + modules/minilinux/templates/page-minilinux.html | 28 + modules/news.inc.php | 167 - modules/news/config.json | 4 + modules/news/module.inc.php | 167 + modules/news/templates/page-news.html | 57 + modules/serversetup.inc.php | 141 - modules/serversetup/config.json | 4 + modules/serversetup/module.inc.php | 186 + modules/serversetup/templates/ipaddress.html | 34 + modules/serversetup/templates/ipxe.html | 149 + modules/serversetup/templates/ipxe_update.html | 20 + modules/session.inc.php | 38 - modules/session/config.json | 4 + modules/session/module.inc.php | 36 + modules/session/templates/page-login.html | 11 + modules/statistics.inc.php | 785 - modules/statistics/config.json | 5 + modules/statistics/module.inc.php | 792 + modules/statistics/templates/clientlist.html | 45 + modules/statistics/templates/cpumodels.html | 51 + modules/statistics/templates/id44.html | 48 + modules/statistics/templates/kvmstate.html | 47 + modules/statistics/templates/machine-hdds.html | 67 + modules/statistics/templates/machine-main.html | 124 + modules/statistics/templates/machine-notes.html | 17 + modules/statistics/templates/machine-usage.html | 51 + modules/statistics/templates/memory.html | 47 + modules/statistics/templates/newclients.html | 44 + modules/statistics/templates/summary.html | 33 + modules/statistics/templates/syslog.html | 43 + modules/support/config.json | 4 + modules/support/module.inc.php | 77 + modules/support/templates/go-pear.phar | 99492 +++++++++++++++++++ modules/support/templates/page-faq.html | 58 + modules/support/templates/page-support.html | 67 + modules/sysconfig.inc.php | 391 - modules/sysconfig/addconfig.inc.php | 4 +- modules/sysconfig/addmodule.inc.php | 31 +- modules/sysconfig/addmodule_adauth.inc.php | 108 +- modules/sysconfig/addmodule_branding.inc.php | 4 +- modules/sysconfig/addmodule_custommodule.inc.php | 4 +- modules/sysconfig/addmodule_ldapauth.inc.php | 92 +- modules/sysconfig/addmodule_sshconfig.inc.php | 2 +- modules/sysconfig/config.json | 4 + modules/sysconfig/module.inc.php | 396 + modules/sysconfig/templates/_page.html | 227 + modules/sysconfig/templates/ad-finish.html | 29 + modules/sysconfig/templates/ad-selfsearch.html | 112 + modules/sysconfig/templates/ad-start.html | 121 + .../templates/ad_ldap-checkconnection.html | 91 + .../templates/ad_ldap-checkcredentials.html | 67 + modules/sysconfig/templates/branding-check.html | 26 + modules/sysconfig/templates/branding-start.html | 25 + modules/sysconfig/templates/cfg-finish.html | 12 + modules/sysconfig/templates/cfg-start.html | 39 + .../sysconfig/templates/config-module-list.html | 17 + modules/sysconfig/templates/custom-filelist.html | 16 + modules/sysconfig/templates/custom-fileselect.html | 31 + modules/sysconfig/templates/custom-upload.html | 18 + modules/sysconfig/templates/ldap-finish.html | 29 + modules/sysconfig/templates/ldap-start.html | 101 + modules/sysconfig/templates/sshconfig-start.html | 27 + modules/sysconfig/templates/start.html | 12 + modules/sysconfignew/config.json | 4 + modules/sysconfignew/module.inc.php | 113 + modules/sysconfignew/templates/_pagenew.html | 190 + modules/sysconfignew/templates/module-editor.html | 269 + modules/syslog.inc.php | 94 - modules/syslog/config.json | 4 + modules/syslog/module.inc.php | 94 + modules/syslog/templates/page-syslog.html | 58 + modules/systemstatus.inc.php | 361 - modules/systemstatus/config.json | 4 + modules/systemstatus/module.inc.php | 361 + modules/systemstatus/templates/_page.html | 129 + modules/systemstatus/templates/addresses.html | 8 + modules/systemstatus/templates/diskstat.html | 63 + modules/systemstatus/templates/services.html | 6 + modules/systemstatus/templates/systeminfo.html | 115 + modules/translation.inc.php | 491 - modules/translation/config.json | 4 + modules/translation/module.inc.php | 597 + modules/translation/templates/_page.html | 17 + modules/translation/templates/edit.html | 71 + modules/translation/templates/module-list.html | 32 + modules/translation/templates/template-list.html | 32 + modules/usermanagement/config.json | 5 + modules/usermanagement/module.inc.php | 109 + .../usermanagement/templates/user-management.html | 127 + modules/vmstore.inc.php | 63 - modules/vmstore/config.json | 4 + modules/vmstore/module.inc.php | 63 + modules/vmstore/templates/mount.html | 25 + modules/vmstore/templates/page-vmstore.html | 111 + modules/webinterface.inc.php | 85 - modules/webinterface/config.json | 4 + modules/webinterface/module.inc.php | 85 + modules/webinterface/templates/httpd-restart.html | 6 + modules/webinterface/templates/https.html | 60 + modules/webinterface/templates/passwords.html | 25 + script/bootstrap-switch.js | 710 + style/bootstrap-switch.css | 196 + style/categories.json | 7 + style/default.css | 192 +- templates/backup/_page.html | 41 - templates/backup/restore.html | 61 - templates/baseconfig/_page.html | 42 - templates/dialog-generic.html | 13 - templates/dozmod/images-delete.html | 57 - templates/dozmod/mailconfig.html | 91 - templates/dozmod/orglist.html | 51 - templates/dozmod/userlist.html | 62 - templates/eventlog/_page.html | 41 - templates/footer.html | 2 - templates/internetaccess/_page.html | 40 - templates/internetaccess/restart.html | 22 - templates/locations/location-subnets.html | 73 - templates/locations/locations.html | 96 - templates/locations/subnets.html | 35 - templates/main-menu.html | 83 - templates/messagebox-error.html | 1 - templates/messagebox-info.html | 1 - templates/messagebox-success.html | 1 - templates/messagebox-warning.html | 1 - templates/minilinux/download.html | 1 - templates/minilinux/filelist.html | 77 - templates/page-adduser.html | 28 - templates/page-login.html | 11 - templates/page-main-guest.html | 13 - templates/page-main.html | 35 - templates/page-minilinux.html | 14 - templates/page-news.html | 57 - templates/page-syslog.html | 58 - templates/page-vmstore.html | 111 - templates/pagenav.html | 16 - templates/serversetup/ipaddress.html | 34 - templates/serversetup/ipxe.html | 70 - templates/serversetup/ipxe_update.html | 20 - templates/statistics/clientlist.html | 45 - templates/statistics/cpumodels.html | 51 - templates/statistics/id44.html | 48 - templates/statistics/kvmstate.html | 47 - templates/statistics/machine-hdds.html | 67 - templates/statistics/machine-main.html | 124 - templates/statistics/machine-notes.html | 17 - templates/statistics/machine-usage.html | 51 - templates/statistics/memory.html | 47 - templates/statistics/newclients.html | 44 - templates/statistics/summary.html | 33 - templates/statistics/syslog.html | 43 - templates/sysconfig/_page.html | 227 - templates/sysconfig/ad-finish.html | 29 - templates/sysconfig/ad-selfsearch.html | 112 - templates/sysconfig/ad-start.html | 121 - templates/sysconfig/ad_ldap-checkconnection.html | 91 - templates/sysconfig/ad_ldap-checkcredentials.html | 67 - templates/sysconfig/ad_ldap-homedir.html | 79 - templates/sysconfig/branding-check.html | 26 - templates/sysconfig/branding-start.html | 25 - templates/sysconfig/cfg-finish.html | 12 - templates/sysconfig/cfg-start.html | 39 - templates/sysconfig/config-module-list.html | 17 - templates/sysconfig/custom-filelist.html | 16 - templates/sysconfig/custom-fileselect.html | 31 - templates/sysconfig/custom-upload.html | 18 - templates/sysconfig/ldap-finish.html | 29 - templates/sysconfig/ldap-start.html | 101 - templates/sysconfig/sshconfig-start.html | 27 - templates/sysconfig/start.html | 12 - templates/systemstatus/_page.html | 129 - templates/systemstatus/addresses.html | 8 - templates/systemstatus/diskstat.html | 63 - templates/systemstatus/services.html | 6 - templates/systemstatus/systeminfo.html | 115 - templates/tm-callback-trigger.html | 15 - templates/translation/_page.html | 15 - templates/translation/edit.html | 71 - templates/translation/template-list.html | 32 - templates/vmstore/mount.html | 25 - templates/webinterface/httpd-restart.html | 6 - templates/webinterface/https.html | 60 - templates/webinterface/passwords.html | 25 - 429 files changed, 111182 insertions(+), 8424 deletions(-) create mode 100644 TODO create mode 100644 fonts/loader.gif create mode 100644 lang/de/modules/adduser.json create mode 100644 lang/de/modules/backup.json delete mode 100644 lang/de/templates/sysconfig/ad_ldap-homedir.json create mode 100644 lang/en/modules/backup/_page.json create mode 100644 lang/en/modules/backup/restore.json create mode 100644 lang/en/modules/baseconfig/_page.json create mode 100644 lang/en/modules/citymanagement.json create mode 100644 lang/en/modules/dozmod/images-delete.json create mode 100644 lang/en/modules/dozmod/mailconfig.json create mode 100644 lang/en/modules/dozmod/orglist.json create mode 100644 lang/en/modules/dozmod/userlist.json create mode 100644 lang/en/modules/eventlog/_page.json create mode 100644 lang/en/modules/internetaccess/_page.json create mode 100644 lang/en/modules/internetaccess/restart.json create mode 100644 lang/en/modules/locations/location-subnets.json create mode 100644 lang/en/modules/locations/locations.json create mode 100644 lang/en/modules/locations/subnets.json create mode 100644 lang/en/modules/main.json create mode 100644 lang/en/modules/main/dialog-generic.json create mode 100644 lang/en/modules/main/main-menu.json create mode 100644 lang/en/modules/main/messagebox-warning.json create mode 100644 lang/en/modules/main/page-main-guest.json create mode 100644 lang/en/modules/main/page-main.json create mode 100644 lang/en/modules/messagebox-error.json create mode 100644 lang/en/modules/messagebox-info.json create mode 100644 lang/en/modules/messagebox-success.json create mode 100644 lang/en/modules/minilinux/download.json create mode 100644 lang/en/modules/minilinux/filelist.json create mode 100644 lang/en/modules/news/page-news.json create mode 100644 lang/en/modules/page-adduser.json create mode 100644 lang/en/modules/page-minilinux.json create mode 100644 lang/en/modules/pagenav.json create mode 100644 lang/en/modules/serversetup/ipaddress.json create mode 100644 lang/en/modules/serversetup/ipxe.json create mode 100644 lang/en/modules/serversetup/ipxe_update.json create mode 100644 lang/en/modules/session/page-login.json create mode 100644 lang/en/modules/statistics/clientlist.json create mode 100644 lang/en/modules/statistics/cpumodels.json create mode 100644 lang/en/modules/statistics/id44.json create mode 100644 lang/en/modules/statistics/kvmstate.json create mode 100644 lang/en/modules/statistics/machine-hdds.json create mode 100644 lang/en/modules/statistics/machine-main.json create mode 100644 lang/en/modules/statistics/machine-notes.json create mode 100644 lang/en/modules/statistics/machine-usage.json create mode 100644 lang/en/modules/statistics/memory.json create mode 100644 lang/en/modules/statistics/newclients.json create mode 100644 lang/en/modules/statistics/summary.json create mode 100644 lang/en/modules/statistics/syslog.json create mode 100644 lang/en/modules/sysconfig/_page.json create mode 100644 lang/en/modules/sysconfig/ad-finish.json create mode 100644 lang/en/modules/sysconfig/ad-selfsearch.json create mode 100644 lang/en/modules/sysconfig/ad-start.json create mode 100644 lang/en/modules/sysconfig/ad_ldap-checkconnection.json create mode 100644 lang/en/modules/sysconfig/ad_ldap-checkcredentials.json create mode 100644 lang/en/modules/sysconfig/ad_ldap-homedir.json create mode 100644 lang/en/modules/sysconfig/branding-check.json create mode 100644 lang/en/modules/sysconfig/branding-start.json create mode 100644 lang/en/modules/sysconfig/cfg-finish.json create mode 100644 lang/en/modules/sysconfig/cfg-start.json create mode 100644 lang/en/modules/sysconfig/config-module-list.json create mode 100644 lang/en/modules/sysconfig/custom-filelist.json create mode 100644 lang/en/modules/sysconfig/custom-fileselect.json create mode 100644 lang/en/modules/sysconfig/custom-upload.json create mode 100644 lang/en/modules/sysconfig/ldap-checkconnection.json create mode 100644 lang/en/modules/sysconfig/ldap-checkcredentials.json create mode 100644 lang/en/modules/sysconfig/ldap-finish.json create mode 100644 lang/en/modules/sysconfig/ldap-start.json create mode 100644 lang/en/modules/sysconfig/sshconfig-start.json create mode 100644 lang/en/modules/sysconfig/start.json create mode 100644 lang/en/modules/syslog/page-syslog.json create mode 100644 lang/en/modules/systemstatus/_page.json create mode 100644 lang/en/modules/systemstatus/addresses.json create mode 100644 lang/en/modules/systemstatus/diskstat.json create mode 100644 lang/en/modules/systemstatus/services.json create mode 100644 lang/en/modules/systemstatus/systeminfo.json create mode 100644 lang/en/modules/translation/_page.json create mode 100644 lang/en/modules/translation/edit.json create mode 100644 lang/en/modules/translation/template-list.json create mode 100644 lang/en/modules/usermanagement/user-management.json create mode 100644 lang/en/modules/vmstore/mount.json create mode 100644 lang/en/modules/vmstore/page-vmstore.json create mode 100644 lang/en/modules/webinterface/httpd-restart.json create mode 100644 lang/en/modules/webinterface/https.json create mode 100644 lang/en/modules/webinterface/passwords.json delete mode 100644 lang/en/templates/backup/_page.json delete mode 100644 lang/en/templates/backup/restore.json delete mode 100644 lang/en/templates/baseconfig/_page.json delete mode 100644 lang/en/templates/dialog-generic.json delete mode 100644 lang/en/templates/dozmod/images-delete.json delete mode 100644 lang/en/templates/dozmod/mailconfig.json delete mode 100644 lang/en/templates/dozmod/orglist.json delete mode 100644 lang/en/templates/dozmod/userlist.json delete mode 100644 lang/en/templates/eventlog/_page.json delete mode 100644 lang/en/templates/internetaccess/_page.json delete mode 100644 lang/en/templates/internetaccess/restart.json delete mode 100644 lang/en/templates/locations/location-subnets.json delete mode 100644 lang/en/templates/locations/locations.json delete mode 100644 lang/en/templates/locations/subnets.json delete mode 100644 lang/en/templates/main-menu.json delete mode 100644 lang/en/templates/messagebox-error.json delete mode 100644 lang/en/templates/messagebox-info.json delete mode 100644 lang/en/templates/messagebox-success.json delete mode 100644 lang/en/templates/messagebox-warning.json delete mode 100644 lang/en/templates/minilinux/download.json delete mode 100644 lang/en/templates/minilinux/filelist.json delete mode 100644 lang/en/templates/page-adduser.json delete mode 100644 lang/en/templates/page-login.json delete mode 100644 lang/en/templates/page-main-guest.json delete mode 100644 lang/en/templates/page-main.json delete mode 100644 lang/en/templates/page-minilinux.json delete mode 100644 lang/en/templates/page-news.json delete mode 100644 lang/en/templates/page-syslog.json delete mode 100644 lang/en/templates/page-vmstore.json delete mode 100644 lang/en/templates/pagenav.json delete mode 100644 lang/en/templates/serversetup/ipaddress.json delete mode 100644 lang/en/templates/serversetup/ipxe.json delete mode 100644 lang/en/templates/serversetup/ipxe_update.json delete mode 100644 lang/en/templates/statistics/clientlist.json delete mode 100644 lang/en/templates/statistics/cpumodels.json delete mode 100644 lang/en/templates/statistics/id44.json delete mode 100644 lang/en/templates/statistics/kvmstate.json delete mode 100644 lang/en/templates/statistics/machine-hdds.json delete mode 100644 lang/en/templates/statistics/machine-main.json delete mode 100644 lang/en/templates/statistics/machine-notes.json delete mode 100644 lang/en/templates/statistics/machine-usage.json delete mode 100644 lang/en/templates/statistics/memory.json delete mode 100644 lang/en/templates/statistics/newclients.json delete mode 100644 lang/en/templates/statistics/summary.json delete mode 100644 lang/en/templates/statistics/syslog.json delete mode 100644 lang/en/templates/sysconfig/_page.json delete mode 100644 lang/en/templates/sysconfig/ad-finish.json delete mode 100644 lang/en/templates/sysconfig/ad-selfsearch.json delete mode 100644 lang/en/templates/sysconfig/ad-start.json delete mode 100644 lang/en/templates/sysconfig/ad_ldap-checkconnection.json delete mode 100644 lang/en/templates/sysconfig/ad_ldap-checkcredentials.json delete mode 100644 lang/en/templates/sysconfig/ad_ldap-homedir.json delete mode 100644 lang/en/templates/sysconfig/branding-check.json delete mode 100644 lang/en/templates/sysconfig/branding-start.json delete mode 100644 lang/en/templates/sysconfig/cfg-finish.json delete mode 100644 lang/en/templates/sysconfig/cfg-start.json delete mode 100644 lang/en/templates/sysconfig/config-module-list.json delete mode 100644 lang/en/templates/sysconfig/custom-filelist.json delete mode 100644 lang/en/templates/sysconfig/custom-fileselect.json delete mode 100644 lang/en/templates/sysconfig/custom-upload.json delete mode 100644 lang/en/templates/sysconfig/ldap-checkconnection.json delete mode 100644 lang/en/templates/sysconfig/ldap-checkcredentials.json delete mode 100644 lang/en/templates/sysconfig/ldap-finish.json delete mode 100644 lang/en/templates/sysconfig/ldap-start.json delete mode 100644 lang/en/templates/sysconfig/sshconfig-start.json delete mode 100644 lang/en/templates/sysconfig/start.json delete mode 100644 lang/en/templates/systemstatus/_page.json delete mode 100644 lang/en/templates/systemstatus/addresses.json delete mode 100644 lang/en/templates/systemstatus/diskstat.json delete mode 100644 lang/en/templates/systemstatus/services.json delete mode 100644 lang/en/templates/systemstatus/systeminfo.json delete mode 100644 lang/en/templates/translation/_page.json delete mode 100644 lang/en/templates/translation/edit.json delete mode 100644 lang/en/templates/translation/template-list.json delete mode 100644 lang/en/templates/vmstore/mount.json delete mode 100644 lang/en/templates/webinterface/httpd-restart.json delete mode 100644 lang/en/templates/webinterface/https.json delete mode 100644 lang/en/templates/webinterface/passwords.json delete mode 100644 lang/pt/templates/sysconfig/ad_ldap-homedir.json delete mode 100644 modules/adduser.inc.php create mode 100644 modules/adduser/config.json create mode 100644 modules/adduser/module.inc.php create mode 100644 modules/adduser/templates/page-adduser.html delete mode 100644 modules/backup.inc.php create mode 100644 modules/backup/config.json create mode 100644 modules/backup/module.inc.php create mode 100644 modules/backup/templates/_page.html create mode 100644 modules/backup/templates/restore.html delete mode 100644 modules/baseconfig.inc.php create mode 100644 modules/baseconfig/config.json create mode 100644 modules/baseconfig/module.inc.php create mode 100644 modules/baseconfig/templates/_page.html create mode 100644 modules/citymanagement/config.json create mode 100644 modules/citymanagement/module.inc.php create mode 100644 modules/citymanagement/templates/page-citymanagement.html delete mode 100644 modules/dozmod.inc.php create mode 100644 modules/dozmod/config.json create mode 100644 modules/dozmod/module.inc.php create mode 100644 modules/dozmod/templates/images-delete.html create mode 100644 modules/dozmod/templates/mailconfig.html create mode 100644 modules/dozmod/templates/orglist.html create mode 100644 modules/dozmod/templates/userlist.html delete mode 100644 modules/eventlog.inc.php create mode 100644 modules/eventlog/config.json create mode 100644 modules/eventlog/module.inc.php create mode 100644 modules/eventlog/templates/_page.html create mode 100644 modules/imgmanagement/config.json create mode 100644 modules/imgmanagement/module.inc.php create mode 100644 modules/imgmanagement/templates/page-imgmanagement.html delete mode 100644 modules/internetaccess.inc.php create mode 100644 modules/internetaccess/config.json create mode 100644 modules/internetaccess/module.inc.php create mode 100644 modules/internetaccess/templates/_page.html create mode 100644 modules/internetaccess/templates/restart.html delete mode 100644 modules/locations.inc.php create mode 100644 modules/locations/config.json create mode 100644 modules/locations/module.inc.php create mode 100644 modules/locations/templates/location-subnets.html create mode 100644 modules/locations/templates/locations.html create mode 100644 modules/locations/templates/subnets.html delete mode 100644 modules/main.inc.php create mode 100644 modules/main/config.json create mode 100644 modules/main/module.inc.php create mode 100644 modules/main/templates/dialog-generic.html create mode 100644 modules/main/templates/footer.html create mode 100644 modules/main/templates/main-menu.html create mode 100644 modules/main/templates/main-menu.html.topnavbar create mode 100644 modules/main/templates/messagebox-error.html create mode 100644 modules/main/templates/messagebox-info.html create mode 100644 modules/main/templates/messagebox-success.html create mode 100644 modules/main/templates/messagebox-warning.html create mode 100644 modules/main/templates/page-login.html create mode 100644 modules/main/templates/page-main-guest.html create mode 100644 modules/main/templates/page-main.html create mode 100644 modules/main/templates/page-minilinux.html create mode 100644 modules/main/templates/page-news.html create mode 100644 modules/main/templates/page-syslog.html create mode 100644 modules/main/templates/page-vmstore.html create mode 100644 modules/main/templates/pagenav.html create mode 100644 modules/main/templates/tm-callback-trigger.html delete mode 100644 modules/minilinux.inc.php create mode 100644 modules/minilinux/config.json create mode 100644 modules/minilinux/module.inc.php create mode 100644 modules/minilinux/templates/download.html create mode 100644 modules/minilinux/templates/filelist.html create mode 100644 modules/minilinux/templates/page-minilinux.html delete mode 100644 modules/news.inc.php create mode 100644 modules/news/config.json create mode 100644 modules/news/module.inc.php create mode 100644 modules/news/templates/page-news.html delete mode 100644 modules/serversetup.inc.php create mode 100644 modules/serversetup/config.json create mode 100644 modules/serversetup/module.inc.php create mode 100644 modules/serversetup/templates/ipaddress.html create mode 100644 modules/serversetup/templates/ipxe.html create mode 100644 modules/serversetup/templates/ipxe_update.html delete mode 100644 modules/session.inc.php create mode 100644 modules/session/config.json create mode 100644 modules/session/module.inc.php create mode 100644 modules/session/templates/page-login.html delete mode 100644 modules/statistics.inc.php create mode 100644 modules/statistics/config.json create mode 100644 modules/statistics/module.inc.php create mode 100644 modules/statistics/templates/clientlist.html create mode 100644 modules/statistics/templates/cpumodels.html create mode 100644 modules/statistics/templates/id44.html create mode 100644 modules/statistics/templates/kvmstate.html create mode 100644 modules/statistics/templates/machine-hdds.html create mode 100644 modules/statistics/templates/machine-main.html create mode 100644 modules/statistics/templates/machine-notes.html create mode 100644 modules/statistics/templates/machine-usage.html create mode 100644 modules/statistics/templates/memory.html create mode 100644 modules/statistics/templates/newclients.html create mode 100644 modules/statistics/templates/summary.html create mode 100644 modules/statistics/templates/syslog.html create mode 100644 modules/support/config.json create mode 100644 modules/support/module.inc.php create mode 100644 modules/support/templates/go-pear.phar create mode 100644 modules/support/templates/page-faq.html create mode 100644 modules/support/templates/page-support.html delete mode 100644 modules/sysconfig.inc.php create mode 100644 modules/sysconfig/config.json create mode 100644 modules/sysconfig/module.inc.php create mode 100644 modules/sysconfig/templates/_page.html create mode 100644 modules/sysconfig/templates/ad-finish.html create mode 100644 modules/sysconfig/templates/ad-selfsearch.html create mode 100644 modules/sysconfig/templates/ad-start.html create mode 100644 modules/sysconfig/templates/ad_ldap-checkconnection.html create mode 100644 modules/sysconfig/templates/ad_ldap-checkcredentials.html create mode 100644 modules/sysconfig/templates/branding-check.html create mode 100644 modules/sysconfig/templates/branding-start.html create mode 100644 modules/sysconfig/templates/cfg-finish.html create mode 100644 modules/sysconfig/templates/cfg-start.html create mode 100644 modules/sysconfig/templates/config-module-list.html create mode 100644 modules/sysconfig/templates/custom-filelist.html create mode 100644 modules/sysconfig/templates/custom-fileselect.html create mode 100644 modules/sysconfig/templates/custom-upload.html create mode 100644 modules/sysconfig/templates/ldap-finish.html create mode 100644 modules/sysconfig/templates/ldap-start.html create mode 100644 modules/sysconfig/templates/sshconfig-start.html create mode 100644 modules/sysconfig/templates/start.html create mode 100644 modules/sysconfignew/config.json create mode 100644 modules/sysconfignew/module.inc.php create mode 100644 modules/sysconfignew/templates/_pagenew.html create mode 100644 modules/sysconfignew/templates/module-editor.html delete mode 100644 modules/syslog.inc.php create mode 100644 modules/syslog/config.json create mode 100644 modules/syslog/module.inc.php create mode 100644 modules/syslog/templates/page-syslog.html delete mode 100644 modules/systemstatus.inc.php create mode 100644 modules/systemstatus/config.json create mode 100644 modules/systemstatus/module.inc.php create mode 100644 modules/systemstatus/templates/_page.html create mode 100644 modules/systemstatus/templates/addresses.html create mode 100644 modules/systemstatus/templates/diskstat.html create mode 100644 modules/systemstatus/templates/services.html create mode 100644 modules/systemstatus/templates/systeminfo.html delete mode 100644 modules/translation.inc.php create mode 100644 modules/translation/config.json create mode 100644 modules/translation/module.inc.php create mode 100644 modules/translation/templates/_page.html create mode 100644 modules/translation/templates/edit.html create mode 100644 modules/translation/templates/module-list.html create mode 100644 modules/translation/templates/template-list.html create mode 100644 modules/usermanagement/config.json create mode 100644 modules/usermanagement/module.inc.php create mode 100644 modules/usermanagement/templates/user-management.html delete mode 100644 modules/vmstore.inc.php create mode 100644 modules/vmstore/config.json create mode 100644 modules/vmstore/module.inc.php create mode 100644 modules/vmstore/templates/mount.html create mode 100644 modules/vmstore/templates/page-vmstore.html delete mode 100644 modules/webinterface.inc.php create mode 100644 modules/webinterface/config.json create mode 100644 modules/webinterface/module.inc.php create mode 100644 modules/webinterface/templates/httpd-restart.html create mode 100644 modules/webinterface/templates/https.html create mode 100644 modules/webinterface/templates/passwords.html create mode 100644 script/bootstrap-switch.js create mode 100644 style/bootstrap-switch.css create mode 100644 style/categories.json delete mode 100644 templates/backup/_page.html delete mode 100644 templates/backup/restore.html delete mode 100644 templates/baseconfig/_page.html delete mode 100644 templates/dialog-generic.html delete mode 100644 templates/dozmod/images-delete.html delete mode 100644 templates/dozmod/mailconfig.html delete mode 100644 templates/dozmod/orglist.html delete mode 100644 templates/dozmod/userlist.html delete mode 100644 templates/eventlog/_page.html delete mode 100644 templates/footer.html delete mode 100644 templates/internetaccess/_page.html delete mode 100644 templates/internetaccess/restart.html delete mode 100644 templates/locations/location-subnets.html delete mode 100644 templates/locations/locations.html delete mode 100644 templates/locations/subnets.html delete mode 100644 templates/main-menu.html delete mode 100644 templates/messagebox-error.html delete mode 100644 templates/messagebox-info.html delete mode 100644 templates/messagebox-success.html delete mode 100644 templates/messagebox-warning.html delete mode 100644 templates/minilinux/download.html delete mode 100644 templates/minilinux/filelist.html delete mode 100644 templates/page-adduser.html delete mode 100644 templates/page-login.html delete mode 100644 templates/page-main-guest.html delete mode 100644 templates/page-main.html delete mode 100644 templates/page-minilinux.html delete mode 100644 templates/page-news.html delete mode 100644 templates/page-syslog.html delete mode 100644 templates/page-vmstore.html delete mode 100644 templates/pagenav.html delete mode 100644 templates/serversetup/ipaddress.html delete mode 100644 templates/serversetup/ipxe.html delete mode 100644 templates/serversetup/ipxe_update.html delete mode 100644 templates/statistics/clientlist.html delete mode 100644 templates/statistics/cpumodels.html delete mode 100644 templates/statistics/id44.html delete mode 100644 templates/statistics/kvmstate.html delete mode 100644 templates/statistics/machine-hdds.html delete mode 100644 templates/statistics/machine-main.html delete mode 100644 templates/statistics/machine-notes.html delete mode 100644 templates/statistics/machine-usage.html delete mode 100644 templates/statistics/memory.html delete mode 100644 templates/statistics/newclients.html delete mode 100644 templates/statistics/summary.html delete mode 100644 templates/statistics/syslog.html delete mode 100644 templates/sysconfig/_page.html delete mode 100644 templates/sysconfig/ad-finish.html delete mode 100644 templates/sysconfig/ad-selfsearch.html delete mode 100644 templates/sysconfig/ad-start.html delete mode 100644 templates/sysconfig/ad_ldap-checkconnection.html delete mode 100644 templates/sysconfig/ad_ldap-checkcredentials.html delete mode 100644 templates/sysconfig/ad_ldap-homedir.html delete mode 100644 templates/sysconfig/branding-check.html delete mode 100644 templates/sysconfig/branding-start.html delete mode 100644 templates/sysconfig/cfg-finish.html delete mode 100644 templates/sysconfig/cfg-start.html delete mode 100644 templates/sysconfig/config-module-list.html delete mode 100644 templates/sysconfig/custom-filelist.html delete mode 100644 templates/sysconfig/custom-fileselect.html delete mode 100644 templates/sysconfig/custom-upload.html delete mode 100644 templates/sysconfig/ldap-finish.html delete mode 100644 templates/sysconfig/ldap-start.html delete mode 100644 templates/sysconfig/sshconfig-start.html delete mode 100644 templates/sysconfig/start.html delete mode 100644 templates/systemstatus/_page.html delete mode 100644 templates/systemstatus/addresses.html delete mode 100644 templates/systemstatus/diskstat.html delete mode 100644 templates/systemstatus/services.html delete mode 100644 templates/systemstatus/systeminfo.html delete mode 100644 templates/tm-callback-trigger.html delete mode 100644 templates/translation/_page.html delete mode 100644 templates/translation/edit.html delete mode 100644 templates/translation/template-list.html delete mode 100644 templates/vmstore/mount.html delete mode 100644 templates/webinterface/httpd-restart.html delete mode 100644 templates/webinterface/https.html delete mode 100644 templates/webinterface/passwords.html diff --git a/TODO b/TODO new file mode 100644 index 00000000..d91865ba --- /dev/null +++ b/TODO @@ -0,0 +1,5 @@ +fix translations path (lang//...) for de, pt +fix translations page for templates/modules +fix sql setup scripts for c3sl's new stuff +rework/fix c3sl's partition / user config variables (baseconfig) + diff --git a/fonts/loader.gif b/fonts/loader.gif new file mode 100644 index 00000000..d0bce154 Binary files /dev/null and b/fonts/loader.gif differ diff --git a/inc/configmodule/adauth.inc.php b/inc/configmodule/adauth.inc.php index 9fe32f43..efc8afd7 100644 --- a/inc/configmodule/adauth.inc.php +++ b/inc/configmodule/adauth.inc.php @@ -14,8 +14,7 @@ class ConfigModule_AdAuth extends ConfigModule const VERSION = 1; private static $REQUIRED_FIELDS = array('server', 'searchbase', 'binddn'); - private static $OPTIONAL_FIELDS = array('bindpw', 'home', 'ssl', 'fingerprint', 'certificate', 'homeattr', - 'shareRemapMode', 'shareRemapCreate', 'shareDocuments', 'shareDownloads', 'shareDesktop', 'shareMedia', 'shareOther', 'shareHomeDrive'); + private static $OPTIONAL_FIELDS = array('bindpw', 'home', 'ssl', 'fingerprint', 'certificate', 'homeattr'); protected function generateInternal($tgz, $parent) { diff --git a/inc/configmodule/ldapauth.inc.php b/inc/configmodule/ldapauth.inc.php index 118e324f..67b1997a 100644 --- a/inc/configmodule/ldapauth.inc.php +++ b/inc/configmodule/ldapauth.inc.php @@ -14,8 +14,7 @@ class ConfigModule_LdapAuth extends ConfigModule const VERSION = 1; private static $REQUIRED_FIELDS = array('server', 'searchbase'); - private static $OPTIONAL_FIELDS = array('binddn', 'bindpw', 'home', 'ssl', 'fingerprint', 'certificate', - 'shareRemapMode', 'shareRemapCreate', 'shareDocuments', 'shareDownloads', 'shareDesktop', 'shareMedia', 'shareOther', 'shareHomeDrive'); + private static $OPTIONAL_FIELDS = array('binddn', 'bindpw', 'home', 'ssl', 'fingerprint', 'certificate'); protected function generateInternal($tgz, $parent) { diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php index fc509112..ec4f4195 100644 --- a/inc/dictionary.inc.php +++ b/inc/dictionary.inc.php @@ -51,21 +51,26 @@ class Dictionary define('LANG', $language); } - public static function getArrayTemplate($template, $lang = false) + public static function getArrayTemplate($template, $module = false, $lang = false) { - return self::getArray('templates/' . $template, $lang); + return self::getArray($module . "/" . $template, $lang); } - public static function getArray($section, $lang = false) + public static function getArray($module, $lang = false, $isMessage = false) { if ($lang === false) $lang = LANG; - $file = Util::safePath("lang/" . $lang . "/" . $section . ".json"); + if(!$isMessage) + $file = Util::safePath("lang/" . $lang . "/modules/" . $module . ".json"); + else + $file = Util::safePath("lang/" . $lang . "/" . $module . ".json"); + if (isset(self::$stringCache[$file])) return self::$stringCache[$file]; $content = @file_get_contents($file); - if ($content === false) // File does not exist for language + if ($content === false) {// File does not exist for language { return array(); + } $json = json_decode($content, true); if (!is_array($json)) return array(); @@ -83,9 +88,10 @@ class Dictionary return "(missing: $string :missing)"; return self::$hardcodedMessages[$string]; } - $strings = self::getArray($section); - if (!isset($strings[$string])) + $strings = self::getArray($section, false, true); + if (!isset($strings[$string])) { return "(missing: '$string' in '$section')"; + } return $strings[$string]; } diff --git a/inc/event.inc.php b/inc/event.inc.php index e014666a..01a148b0 100644 --- a/inc/event.inc.php +++ b/inc/event.inc.php @@ -26,7 +26,8 @@ class Event $mountId = Trigger::mount(); $autoIp = Trigger::autoUpdateServerIp(); $ldadpId = Trigger::ldadp(); - + $ipxeId = Trigger::ipxe(); + Taskmanager::submit('DozmodLauncher', array( 'operation' => 'start' )); @@ -59,6 +60,17 @@ class Event EventLog::failure("The server's IP address could not be determined automatically, and there is no valid address configured."); $everythingFine = false; } + // iPXE generation + if ($ipxeId === false) { + EventLog::failure('Cannot generate PXE menu: Taskmanager unreachable!'); + $everythingFine = false; + } else { + $res = Taskmanager::waitComplete($ipxeId, 5000); + if (Taskmanager::isFailed($res)) { + EventLog::failure('Update PXE Menu failed', $res['data']['error']); + $everythingFine = false; + } + } // Just so we know booting is done (and we don't expect any more errors from booting up) if ($everythingFine) { @@ -73,11 +85,9 @@ class Event */ public static function serverIpChanged() { + error_log('Server ip changed'); global $tidIpxe; $tidIpxe = Trigger::ipxe(); - if (is_string($tidIpxe)) { - TaskmanagerCallback::addCallback($tidIpxe, 'cbIpxeBuilt'); - } ConfigModule::serverIpChanged(); } @@ -86,6 +96,7 @@ class Event */ public static function activeConfigChanged() { + error_log('Active config changed'); $task = Trigger::ldadp(); TaskmanagerCallback::addCallback($task, 'ldadpStartup'); } diff --git a/inc/message.inc.php b/inc/message.inc.php index 472811ff..d2fd74b9 100644 --- a/inc/message.inc.php +++ b/inc/message.inc.php @@ -59,20 +59,22 @@ class Message foreach ($item['params'] as $index => $text) { $message = str_replace('{{' . $index . '}}', '' . htmlspecialchars($text) . '', $message); } - echo Render::parse('messagebox-' . $item['type'], array('message' => $message)); + echo Render::parse('messagebox-' . $item['type'], array('message' => $message), 'main'); } self::$list = array(); return; } // Non-Ajax + if (!self::$flushed) Render::openTag('div', array('class' => 'container')); foreach (self::$list as $item) { $message = Dictionary::getMessage($item['id']); foreach ($item['params'] as $index => $text) { $message = str_replace('{{' . $index . '}}', '' . htmlspecialchars($text) . '', $message); } - Render::addTemplate('messagebox-' . $item['type'], array('message' => $message)); + Render::addTemplate('messagebox-' . $item['type'], array('message' => $message),'main'); self::$alreadyDisplayed[] = $item; } + if (!self::$flushed) Render::closeTag('div'); self::$list = array(); self::$flushed = true; } diff --git a/inc/paginate.inc.php b/inc/paginate.inc.php index 62345ffe..91f52077 100644 --- a/inc/paginate.inc.php +++ b/inc/paginate.inc.php @@ -104,7 +104,7 @@ class Paginate $pages = Render::parse('pagenav', array( 'url' => $this->url, 'pages' => $pages, - )); + ),'main'); $data['page'] = $this->currentPage; $data['pagenav'] = $pages; Render::addTemplate($template, $data); diff --git a/inc/render.inc.php b/inc/render.inc.php index 6de00eee..10d18514 100644 --- a/inc/render.inc.php +++ b/inc/render.inc.php @@ -18,6 +18,7 @@ class Render private static $mustache = false; private static $body = ''; private static $header = ''; + private static $dashboard = ''; private static $footer = ''; private static $title = ''; private static $templateCache = array(); @@ -39,6 +40,9 @@ class Render $zip = isset($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false); if ($zip) ob_start(); + $page = strtolower($_GET['do']); + if(User::isLoggedIn()) + self::createDashboard($page); echo ' @@ -50,6 +54,9 @@ class Render + + + @@ -58,11 +65,15 @@ class Render , ' -
+
+
', + self::$dashboard + , self::$body , '
+
@@ -129,9 +140,9 @@ class Render /** * Add the given template to the output, using the given params for placeholders in the template */ - public static function addTemplate($template, $params = false) + public static function addTemplate($template, $params = false, $module = false) { - self::$body .= self::parse($template, $params); + self::$body .= self::parse($template, $params, $module); } /** @@ -148,7 +159,7 @@ class Render 'title' => $title, 'next' => $next, 'body' => self::parse($template, $params) - )); + ), 'main'); } /** @@ -164,15 +175,19 @@ class Render * @param string $template name of template, relative to templates/, without .html extension * @return string Rendered template */ - public static function parse($template, $params = false) + public static function parse($template, $params = false, $module = false) { // Load html snippet - $html = self::getTemplate($template); + $html = self::getTemplate($template,$module); if ($html === false) { return '

Template ' . htmlspecialchars($template) . '

' . nl2br(htmlspecialchars(print_r($params, true))) . '
'; } // Get all translated strings for this template - $dictionary = Dictionary::getArrayTemplate($template); + if($module === false){ + $module = strtolower(empty($_REQUEST['do']) ? 'main' : $_REQUEST['do']); + } + $dictionary = Dictionary::getArrayTemplate($template, $module); + // Now find all language tags in this array preg_match_all('/{{(lang_.+?)}}/', $html, $out); foreach ($out[1] as $tag) { @@ -183,7 +198,7 @@ class Render // Always add token to parameter list if (is_array($params) || $params === false || is_null($params)) $params['token'] = Session::get('token'); - // Likewise, add currently selected language (its two letter code) to params + // Likewise, add currently selected language ( its two letter code) to params $params['current_lang'] = LANG; // Add desired password field type $params['password_type'] = Property::getPasswordFieldType(); @@ -224,15 +239,66 @@ class Render /** * Private helper: Load the given template and return it */ - private static function getTemplate($template) + private static function getTemplate($template, $module = false) { if (isset(self::$templateCache[$template])) { return self::$templateCache[$template]; } + // Select current module + if(!$module){ + $module = strtolower(empty($_REQUEST['do']) ? 'Main' : $_REQUEST['do']); + } // Load from disk - $data = @file_get_contents('templates/' . $template . '.html'); + $data = @file_get_contents('modules/' . $module . '/templates/' . $template . '.html'); + if ($data === false) + $data = 'Non-existent template ' . $template . ' requested!'; self::$templateCache[$template] = & $data; return $data; } + /** + * Create the dashboard menu + */ + private static function createDashboard($page) + { + // Check all required modules + $requiredModules = array('adduser','main','session','translation','usermanagement'); + $notFound = ''; + foreach ($requiredModules as $module) { + if(!is_dir('modules/' . $module . '/')){ + $notFound .= '\'' . $module . '\' '; + } + } + if(strlen($notFound) > 0){ + Util::traceError('At least one required module was not found: ' . $notFound); + }else{ + $modules = array_diff(scandir('modules/'), array('..', '.')); + $categories = array(); + foreach ($modules as $module) { + $json = json_decode(file_get_contents("modules/" . $module . "/config.json"),true); + $categories[$json['category']][] = $module; + } + unset($categories['hidden']); + self::$dashboard = '
'; + } + } + + /** + * get categories glyph icons + */ + private static function getGlyphicon($category){ + return json_decode(file_get_contents("style/categories.json"),true)[$category]; + } + } diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php index efa5aacd..cec763fb 100644 --- a/inc/taskmanagercallback.inc.php +++ b/inc/taskmanagercallback.inc.php @@ -116,13 +116,6 @@ class TaskmanagerCallback EventLog::warning("Could not generate Active Directory configuration", $task['data']['error']); } - public static function cbIpxeBuilt($task) - { - if (Taskmanager::isFailed($task)) { - EventLog::warning("Could not recompile iPXE menu.", $task['data']['error']); - } - } - /** * Generating a config module has finished. * diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php index 0f7e1b13..353d6d69 100644 --- a/inc/trigger.inc.php +++ b/inc/trigger.inc.php @@ -15,6 +15,7 @@ class Trigger * Compile iPXE pxelinux menu. Needs to be done whenever the server's IP * address changes. * + * @param boolean $force force recompilation even if it seems up to date * @return boolean|string false if launching task failed, task-id otherwise */ public static function ipxe() diff --git a/inc/user.inc.php b/inc/user.inc.php index 111849fe..d3cdc65a 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -12,6 +12,13 @@ class User return self::$user !== false; } + public static function getId() + { + if (!self::isLoggedIn()) + return false; + return self::$user['userid']; + } + public static function getName() { if (!self::isLoggedIn()) @@ -58,6 +65,7 @@ class User public static function logout() { + error_log("in logout"); Session::delete(); Header('Location: ?do=Main&fromlogout'); exit(0); @@ -81,4 +89,19 @@ class User return self::$user['lasteventid']; } + public static function addUser($data){ + Database::exec ( "INSERT INTO user SET login = :login, passwd = :pass, fullname = :name, phone = :phone, email = :email, permissions = 4", $data ); + $ret = Database::queryFirst('SELECT userid FROM user WHERE login = :user LIMIT 1', array('user' => $data['login'])); + $user = array( + 'user' => $ret['userid'] + ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '44', size = '5G', mount_point = '/tmp', user = :user", $user ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '43', size = '20G', mount_point = '/boot', options = 'bootable', user = :user", $user ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '40', size = '20G', mount_point = '/cache/export/dnbd3', user = :user", $user ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '41', size = '5G', mount_point = '/home', user = :user", $user ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '82', size = '1G', user = :user", $user ); + Message::addSuccess('add-user'); + EventLog::info ( User::getName () . ' created user ' . $data['login'] ); + } + } diff --git a/index.php b/index.php index 021820b8..84450da5 100644 --- a/index.php +++ b/index.php @@ -53,12 +53,14 @@ abstract class Page * @var \Page */ private static $instance = false; + public static $name = false; public static function set($name) { $name = preg_replace('/[^A-Za-z]/', '', $name); - $modulePath = 'modules/' . strtolower($name) . '.inc.php'; - if (!file_exists($modulePath)) { + $modulePath = 'modules/' . strtolower($name) . '/module.inc.php'; + $moduleConfig = json_decode(file_get_contents('modules/' . strtolower($name) . '/config.json'),true); + if (!file_exists($modulePath) || empty($moduleConfig) || $moduleConfig['enabled'] != 'true') { Util::traceError('Invalid module file: ' . $modulePath); } require_once $modulePath; @@ -67,6 +69,7 @@ abstract class Page Util::traceError('Module not found: ' . $name); } self::$instance = new $className(); + self::$name = strtolower($name); } } @@ -130,7 +133,7 @@ Render::addTemplate('main-menu', array( 'user' => User::getName(), 'warning' => User::getName() !== false && User::getLastSeenEvent() < Property::getLastWarningId(), 'needsSetup' => User::getName() !== false && Property::getNeedsSetup() -)); +),'main'); Message::renderList(); @@ -142,10 +145,10 @@ if (defined('CONFIG_DEBUG') && CONFIG_DEBUG) { } if (defined('CONFIG_FOOTER')) { - Render::addTemplate('footer', array('text' => CONFIG_FOOTER)); + Render::addTemplate('footer', array('text' => CONFIG_FOOTER), 'main'); } -Render::addTemplate('tm-callback-trigger'); +Render::addTemplate('tm-callback-trigger', array(), 'main'); // Send page to client. Render::output(); diff --git a/lang/de/messages-hardcoded.json b/lang/de/messages-hardcoded.json index f785f042..692bc9bc 100644 --- a/lang/de/messages-hardcoded.json +++ b/lang/de/messages-hardcoded.json @@ -4,12 +4,15 @@ "lang_contentOf": "Inhalt von", "lang_createUser": "Benutzer anlegen", "lang_days": "Tag(e)", + "lang_eventLog": "Server Log", "lang_hours": "Stunde(n)", "lang_location": "Lokalisierung", "lang_login": "Anmelden", "lang_moduleAdd": "Modul hinzuf\u00fcgen", "lang_noModuleFromThisGroup": "(Kein Modul dieser Gruppe)", "lang_serverConfiguration": "Serverseitige Konfiguration", + "lang_serverStatus": "Server Status", + "lang_status": "Status", "lang_titleBackup": "Sichern und Wiederherstellen", "lang_titleClientStatistics": "Client-Statistiken", "lang_titleEventLog": "Ereignisprotokoll", diff --git a/lang/de/modules/adduser.json b/lang/de/modules/adduser.json new file mode 100644 index 00000000..0f446025 --- /dev/null +++ b/lang/de/modules/adduser.json @@ -0,0 +1,8 @@ +{ + "lang_confirmation": "Wiederholen", + "lang_createUser": "Benutzer anlegen", + "lang_fullName": "Vollst\u00e4ndiger Name", + "lang_password": "Passwort", + "lang_telephone": "Telefon", + "lang_username": "Benutzerkennung" +} \ No newline at end of file diff --git a/lang/de/modules/backup.json b/lang/de/modules/backup.json new file mode 100644 index 00000000..5e3efea2 --- /dev/null +++ b/lang/de/modules/backup.json @@ -0,0 +1,14 @@ +{ + "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 diff --git a/lang/de/templates/baseconfig/_page.json b/lang/de/templates/baseconfig/_page.json index 5a4e5a6d..0f4819b4 100644 --- a/lang/de/templates/baseconfig/_page.json +++ b/lang/de/templates/baseconfig/_page.json @@ -1,7 +1,15 @@ { "lang_basicConfiguration": "Basiskonfiguration", + "lang_catUser": "Benutzerverwaltung", "lang_clientRelatedConfig": "Die Optionen auf dieser Seite beziehen sich auf das Verhalten der bwLehrpool-Clients.", "lang_close": "Schlie\u00dfen", + "lang_create": "Schaffen", + "lang_delete": "L\u00f6schen", + "lang_help": "Hilfe", + "lang_newUser": "Neuer Benutzer", + "lang_partitionMountPoint": "Mount Point", "lang_reset": "Zur\u00fccksetzen", - "lang_save": "Speichern" + "lang_save": "Speichern", + "lang_userName": "Benutzername", + "lang_userPasswd": "Passwort" } \ No newline at end of file diff --git a/lang/de/templates/page-news.json b/lang/de/templates/page-news.json index d1cf877e..7801584d 100644 --- a/lang/de/templates/page-news.json +++ b/lang/de/templates/page-news.json @@ -1,4 +1,5 @@ { + "lang_activeNews": "Aktive News", "lang_content": "Inhalt", "lang_date": "Datum", "lang_delete": "L\u00f6schen", diff --git a/lang/de/templates/serversetup/ipxe.json b/lang/de/templates/serversetup/ipxe.json index 54a3408b..edce0b5e 100644 --- a/lang/de/templates/serversetup/ipxe.json +++ b/lang/de/templates/serversetup/ipxe.json @@ -4,6 +4,7 @@ "lang_bootMenu": "Bootmen\u00fc", "lang_bootMenuCreate": "Bootmen\u00fc erzeugen", "lang_close": "Schlie\u00dfen", + "lang_compile": "Kompilieren", "lang_customEntry": "Eigener Eintrag", "lang_example": "Beispiel", "lang_localHDD": "Lokale HDD", diff --git a/lang/de/templates/sysconfig/ad_ldap-homedir.json b/lang/de/templates/sysconfig/ad_ldap-homedir.json deleted file mode 100644 index 9d199688..00000000 --- a/lang/de/templates/sysconfig/ad_ldap-homedir.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "lang_folderRedirection": "Folder Redirection", - "lang_handlingNotes": "Hier k\u00f6nnen Sie festlegen, wie Netzwerk-Shares (inkl. des Home-Verzeichnisses) an Virtuelle Maschinen durchgereicht werden. In \u00e4lteren Versionen von bwLehrpool wurden die VMware Shared Folders genutzt, was mit bestimmten file servern Probleme verursachen konnte. Der neue native Modus funktioniert deutlich besser, ist aber bei Windows-G\u00e4sten darauf angewiesen, dass (1) der file server smb\/cifs spricht (z.B. Windows Server, Samba unter Linux) und (2) die openslx.exe im Autostart eingebunden ist (bei den bwLehrpool Vorlagen bereits der Fall). Der native Modus mit Fallback auf VMware ist experimentell und kann dazu f\u00fchren, dass die VM in regelm\u00e4\u00dfigen Abst\u00e4nden H\u00e4nger hat. WICHTIG: Bitte w\u00e4hlen Sie einen Laufwerksbuchstaben, der in den eingesetzten VMs verf\u00fcgbar ist, da ansonsten auf einen anderen Buchstaben ausgewichen werden muss.", - "lang_homedirHandling": "(Home-)Verzeichnis Einbindung", - "lang_mapModeNative": "Nativ direkt in der VM einbinden [openslx.exe]", - "lang_mapModeNativeFallback": "Nativ in der VM einbinden; Fallback auf VMware Shared Folders", - "lang_mapModeNone": "Verzeichnisse nicht durchreichen", - "lang_mapModeVmware": "VMware Shared Folders [VMwareTools]", - "lang_next": "Weiter", - "lang_redirectionWarning": "ACHTUNG: Diese Funktion ist experimentell. Sie biegt nach dem Starten mittels openslx.exe die ausgew\u00e4hlten Verzeichnisse auf das Home-Verzeichnis des angemeldeten Benutzers um (getestet mit Windows 7 und 10). Da hierzu undokumentierte Windows-Einstellungen zur Laufzeit ge\u00e4ndert werden ist nicht garantiert, dass diese Methode in sp\u00e4teren Versionen\/Updates von Windows noch funktioniert. Wir empfehlen, stattdessen die Verzeichnisse - sofern gew\u00fcnscht - bereits in der Vorlage auf den oben konfigurierten Laufwerksbuchstaben des Home-Verzeichnisses umzukonfigurieren.", - "lang_shareDesktop": "Desktop (Achtung: Vom Dozent angelegte Verkn\u00fcpfungen nicht sichtbar!)", - "lang_shareDocuments": "Eigene Dokumente", - "lang_shareDownloads": "Downloads", - "lang_shareHomeDrive": "Home-Verzeichnis Buchstabe (Windows)", - "lang_shareMapCreate": "Ordner auf dem Netzlaufwerk bei Bedarf anlegen", - "lang_shareMedia": "Eigene Musik, Videos, Bilder", - "lang_shareOther": "Andere (Saved Games, Kontakte, Favoriten, ...)", - "lang_shareRemapMode": "Einbindemodus" -} \ No newline at end of file diff --git a/lang/en/messages-hardcoded.json b/lang/en/messages-hardcoded.json index b19ef60a..7c781d4e 100644 --- a/lang/en/messages-hardcoded.json +++ b/lang/en/messages-hardcoded.json @@ -1,21 +1,55 @@ { + "lang_administration": "Translations", + "lang_backup": "Backup", + "lang_baseconfig": "Variables", + "lang_cities":"Cities", + "lang_citymanagement":"Management", + "lang_clientLog": "Client Log", "lang_clientSshConfig": "SSH configuration", "lang_configurationCompilation": "Compile configuration", + "lang_content": "Content", "lang_contentOf": "Content of \"", "lang_createUser": "Create User", "lang_days": "Day(s)", + "lang_dozmod": "Tutor Module", + "lang_eventLog": "Server Log", + "lang_eventlog": "Client Log", "lang_hours": "Hour(s)", - "lang_location": "Location", + "lang_internetaccess": "Internet Access", + "lang_imgmanagement": "Image Management", + "lang_locations": "Room/Locations", "lang_login": "Login", + "lang_minilinux": "Minilinux", + "lang_modules": "Modules", "lang_moduleAdd": "Add Module", + "lang_news": "News", "lang_noModuleFromThisGroup": "(No module from this group)", + "lang_server": "iPXE \/ Boot Menu", "lang_serverConfiguration": "Server-side Configuration", + "lang_serverStatus": "Server", + "lang_serversetup": "iPXE \/ Boot Menu", + "lang_settings": "Settings", + "lang_statistics": "Client Statistics", + "lang_status": "Status", + "lang_support": "Support", + "lang_sysconfig": "Modules", + "lang_syslog": "Server Log", + "lang_systemstatus": "Server", "lang_titleBackup": "Save and Restore", "lang_titleClientStatistics": "Client statistics", "lang_titleEventLog": "Event log", + "lang_translation": "Translation", + "lang_user": "Users", + "lang_userManagement": "Management", + "lang_usermanagement": "Management", + "lang_users": "Users", + "lang_variables": "Variables", + "lang_vmLocation": "Virtual Machine", + "lang_vmstore": "Virtual Machine", "lang_titleWebinterface": "Web Interface", "lang_unknwonTaskManager": "Unknown Task Manager error", + "lang_webinterface": "Web Interface", "today": "Today", "unused": "Unused", "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/lang/en/modules/backup/_page.json b/lang/en/modules/backup/_page.json new file mode 100644 index 00000000..799c6168 --- /dev/null +++ b/lang/en/modules/backup/_page.json @@ -0,0 +1,14 @@ +{ + "lang_backup": "Backup", + "lang_backupDescription": "Here you can backup the complete configuration of this satellite server. This includes lecture and virtual machine meta data. The HDD images of the virtual machines on the vm store are not included in this backup, because of their size. If desired, the store needs to be backed up manually.", + "lang_backupRestore": "Backup and restore", + "lang_browseForFile": "Browse", + "lang_download": "Download", + "lang_dozmodExplanation": "This restores all the virtual machine and lecture meta data created using the \"Dozentenmodul\". Please make sure the VM-storage configured still contains all the VM-Images associated with the virtual machines. If the location of the storage changed, make sure the relative pathes on the share are still the same, otherwise the virtual machines won't be usable.", + "lang_restore": "Upload", + "lang_restoreDescription": "Here you can restore a configuration backup. Please note that this will reboot the server, so it is advised to do this while nobody is using the system. Please note that this will also restore the password for the web interface that was active when the configuration backup was created.", + "lang_restoreDozmodConfig": "Restore Dozentenmodul config", + "lang_restoreSystemConfig": "Restore system config", + "lang_selectFile": "Please select a backup archive", + "lang_systemExplanation": "Restore basic configuration like authentication method, passwords, vm storage location, proxy config, etc. WARNING: If you restore a configuration backup that was made before WS15\/16 (backup format version <10), the system configuration will be restored regardless of this check mark." +} \ No newline at end of file diff --git a/lang/en/modules/backup/restore.json b/lang/en/modules/backup/restore.json new file mode 100644 index 00000000..5a5f6f64 --- /dev/null +++ b/lang/en/modules/backup/restore.json @@ -0,0 +1,8 @@ +{ + "lang_backup": "Backup...", + "lang_reboot": "System reboot", + "lang_restoreConfig": "Restore config", + "lang_restoreFailed": "Restoring configuration failed.", + "lang_stopping": "Stopping", + "lang_waitReboot": "Waiting for reboot." +} \ No newline at end of file diff --git a/lang/en/modules/baseconfig/_page.json b/lang/en/modules/baseconfig/_page.json new file mode 100644 index 00000000..6429a835 --- /dev/null +++ b/lang/en/modules/baseconfig/_page.json @@ -0,0 +1,7 @@ +{ + "lang_basicConfiguration": "Basic Configuration", + "lang_clientRelatedConfig": "The options on this page are related to the bwLehrpool client machines.", + "lang_close": "Close", + "lang_reset": "Reset", + "lang_save": "Save" +} \ No newline at end of file diff --git a/lang/en/modules/citymanagement.json b/lang/en/modules/citymanagement.json new file mode 100644 index 00000000..27bb60c0 --- /dev/null +++ b/lang/en/modules/citymanagement.json @@ -0,0 +1,13 @@ +{ + "lang_cancelConfirm": "Do you really want to remove this city?", + "lang_cityInfo":"Here you can create new cities for the website, besides editing or removing the existing ones", + "lang_cityPage":"Manage cities", + "lang_cityname":"City name", + "lang_close": "Close", + "lang_create": "Create", + "lang_edit":"Edit", + "lang_editcity":"Edit City", + "lang_operations": "Operations", + "lang_remove": "Remove", + "lang_save": "Save" +} diff --git a/lang/en/modules/dozmod/images-delete.json b/lang/en/modules/dozmod/images-delete.json new file mode 100644 index 00000000..fcc8c7e7 --- /dev/null +++ b/lang/en/modules/dozmod/images-delete.json @@ -0,0 +1,12 @@ +{ + "lang_delButton": "Permanently delete selected images", + "lang_delete": "Delete", + "lang_description": "This list shows images that reached their expire date, or where the image file in the file system is damaged or missing. You need to manually confirm the deletion of these files for safety reasons (software bugs, wrong system time, etc.).", + "lang_hasNewer": "Newer version exists", + "lang_heading": "Images marked for deletion", + "lang_image": "VM", + "lang_owner": "Owner", + "lang_size": "Size", + "lang_subHeading": "Expired or damaged images", + "lang_version": "Version timestamp" +} \ No newline at end of file diff --git a/lang/en/modules/dozmod/mailconfig.json b/lang/en/modules/dozmod/mailconfig.json new file mode 100644 index 00000000..0c0dcd7f --- /dev/null +++ b/lang/en/modules/dozmod/mailconfig.json @@ -0,0 +1,21 @@ +{ + "lang_asteriskRequired": "Fields marked with (*) are required", + "lang_host": "Host", + "lang_mailConfig": "SMTP configuration for sending mails", + "lang_mailConfigHeadline": "email configuration", + "lang_mailDescription": "Fill in the following fields if you want to notify tutors\/professors\/lecturers about expiring VMs and lectures. If you leave one of the required fields blank, the feature will be disabled.", + "lang_password": "Password", + "lang_port": "Port", + "lang_replyTo": "Reply-To address", + "lang_save": "Save configuration", + "lang_senderAddress": "Sender address", + "lang_senderName": "Sender's display name", + "lang_ssl": "SSL mode", + "lang_sslExplicit": "Explicit SSL (\"STARTTLS\")", + "lang_sslImplicit": "Implicit SSL", + "lang_sslNone": "No SSL", + "lang_test": "Send test mail", + "lang_testConfiguration": "To test the configuration, enter a recipient address here", + "lang_testRecipient": "Recipient", + "lang_username": "User name (SMTP auth)" +} \ No newline at end of file diff --git a/lang/en/modules/dozmod/orglist.json b/lang/en/modules/dozmod/orglist.json new file mode 100644 index 00000000..37b89e02 --- /dev/null +++ b/lang/en/modules/dozmod/orglist.json @@ -0,0 +1,6 @@ +{ + "lang_canLogin": "Members of this organization can login", + "lang_organization": "Organization", + "lang_organizationList": "List of organizations", + "lang_organizationListHeader": "Set access permissions for organizations" +} \ No newline at end of file diff --git a/lang/en/modules/dozmod/userlist.json b/lang/en/modules/dozmod/userlist.json new file mode 100644 index 00000000..615f1b14 --- /dev/null +++ b/lang/en/modules/dozmod/userlist.json @@ -0,0 +1,12 @@ +{ + "lang_canLogin": "This user can login to this satellite", + "lang_email": "E-Mail", + "lang_emailNotifications": "E-Mail notifications enabled", + "lang_lastLogin": "Last login", + "lang_organization": "Organization", + "lang_superUser": "Is super user (can edit\/delete all lectures and VMs)", + "lang_user": "User name", + "lang_userList": "User list", + "lang_userListDescription": "Here you can promote \"super users\", which will have all permissions in the \"Dozenzenmodul\". You can also ban users from accessing this server via the \"Dozentenmodul\".", + "lang_userListHeader": "Users known to this satellite" +} \ No newline at end of file diff --git a/lang/en/modules/eventlog/_page.json b/lang/en/modules/eventlog/_page.json new file mode 100644 index 00000000..21ec64ea --- /dev/null +++ b/lang/en/modules/eventlog/_page.json @@ -0,0 +1,6 @@ +{ + "lang_details": "Details", + "lang_event": "Event", + "lang_eventLog": "Event log", + "lang_when": "When" +} \ No newline at end of file diff --git a/lang/en/modules/internetaccess/_page.json b/lang/en/modules/internetaccess/_page.json new file mode 100644 index 00000000..c02ca4f5 --- /dev/null +++ b/lang/en/modules/internetaccess/_page.json @@ -0,0 +1,14 @@ +{ + "lang_automatic": "Auto", + "lang_description": "Here you can configure how the satellite server has to access the internet.", + "lang_internetAccess": "Internet access", + "lang_manual": "Manual", + "lang_manualProxyConfig": "If you want to configure a proxy server manually, please supply the credentials here.", + "lang_no": "None", + "lang_proxyAddress": "Address", + "lang_proxyPassword": "Password", + "lang_proxyPort": "Port", + "lang_proxyType": "Proxy type", + "lang_proxyUsername": "User", + "lang_save": "Save" +} \ No newline at end of file diff --git a/lang/en/modules/internetaccess/restart.json b/lang/en/modules/internetaccess/restart.json new file mode 100644 index 00000000..badad460 --- /dev/null +++ b/lang/en/modules/internetaccess/restart.json @@ -0,0 +1,5 @@ +{ + "lang_restartFailed": "Restarting one or more services failed!", + "lang_restarting": "Restarting", + "lang_serviceRestart": "Restart of services" +} \ No newline at end of file diff --git a/lang/en/modules/locations/location-subnets.json b/lang/en/modules/locations/location-subnets.json new file mode 100644 index 00000000..2ba94384 --- /dev/null +++ b/lang/en/modules/locations/location-subnets.json @@ -0,0 +1,18 @@ +{ + "lang_addNewSubnet": "Add new subnet", + "lang_assignSubnetExplanation": "Client machines which fall into an IP range listed below will be assigned to this location and will see an according lecture list (e.g. they will see lectures that are exclusively assigned to this location).", + "lang_assignedSubnets": "Assigned subnets \/ IP ranges", + "lang_deleteChildLocations": "Delete child locations aswell", + "lang_deleteLocation": "Delete location", + "lang_deleteSubnet": "Delete range", + "lang_endAddress": "End address", + "lang_locationInfo": "Location details", + "lang_locationSettings": "Edit this room or location", + "lang_matchingMachines": "Matching clients", + "lang_name": "Name", + "lang_parentLocation": "Parent location", + "lang_referencingLectures": "Assigned Lectures", + "lang_save": "Save", + "lang_startAddress": "Start address", + "lang_subnet": "IP range" +} \ No newline at end of file diff --git a/lang/en/modules/locations/locations.json b/lang/en/modules/locations/locations.json new file mode 100644 index 00000000..db4fd0a7 --- /dev/null +++ b/lang/en/modules/locations/locations.json @@ -0,0 +1,10 @@ +{ + "lang_areYouSureNoUndo": "Are you sure? This cannot be undone!", + "lang_edit": "Edit", + "lang_location": "Ort", + "lang_locationName": "Name", + "lang_locationsMainHeading": "Manage rooms and locations", + "lang_noParent": "No parent", + "lang_save": "Save", + "lang_thisListBySubnet": "List by subnet" +} \ No newline at end of file diff --git a/lang/en/modules/locations/subnets.json b/lang/en/modules/locations/subnets.json new file mode 100644 index 00000000..65da254b --- /dev/null +++ b/lang/en/modules/locations/subnets.json @@ -0,0 +1,7 @@ +{ + "lang_endAddress": "End", + "lang_listOfSubnets": "List of subnets", + "lang_location": "Location", + "lang_startAddress": "Start", + "lang_thisListByLocation": "List by location" +} \ No newline at end of file diff --git a/lang/en/modules/main.json b/lang/en/modules/main.json new file mode 100644 index 00000000..32d9b177 --- /dev/null +++ b/lang/en/modules/main.json @@ -0,0 +1,33 @@ +{ + "lang_backup": "Backup\/Restore", + "lang_client": "Client", + "lang_clientLog": "Client Log", + "lang_clientStats": "Client statistics", + "lang_configurationBasic": "PXE\/Boot", + "lang_configurationVariables": "Configuration Variables", + "lang_dozmod": "Tutor module", + "lang_eventLog": "Server Log", + "lang_internetAccess": "Internet access", + "lang_intro": "Esta \u00e9 a interface de configura\u00e7\u00e3o do OpenSLX.", + "lang_introGuest": "This is the administration interface of the local bwLehrpool intallation. Please authenticate yourself to adjust settings.", + "lang_language": "Language", + "lang_localization": "Localization", + "lang_locations": "Rooms\/Locations", + "lang_login": "Login", + "lang_logout": "Logout", + "lang_needsSetup": "Setup incomplete", + "lang_next": "Next", + "lang_noExistingAccount": "No account has been created yet. Sign up to become the administrator.", + "lang_register": "Register", + "lang_warning": "Warning", + "lang_welcome": "Welcome", + "lang_bootMenuWarning": "The boot menu is outdated or has not been generated.", + "lang_configure": "Configure", + "lang_intro": "This is the bwLehrpool configuration interface.", + "lang_minilinuxMissing": "Important files from the mini Linux installation are missing.", + "lang_numerOfImagesMarkedForDeletion": "Images marked for deletion", + "lang_systemConfiguration": "System Configuration", + "lang_systemConfigurationNotChosen": "A system configuration has not been chosen yet.", + "lang_vmLocationNotSet": "A location for the virtual machine is not set yet.", + "lang_welcome": "Welcome" +} diff --git a/lang/en/modules/main/dialog-generic.json b/lang/en/modules/main/dialog-generic.json new file mode 100644 index 00000000..c7551ed3 --- /dev/null +++ b/lang/en/modules/main/dialog-generic.json @@ -0,0 +1,3 @@ +{ + "lang_next": "Next" +} \ No newline at end of file diff --git a/lang/en/modules/main/main-menu.json b/lang/en/modules/main/main-menu.json new file mode 100644 index 00000000..d22f90d7 --- /dev/null +++ b/lang/en/modules/main/main-menu.json @@ -0,0 +1,26 @@ +{ + "lang_backup": "Backup\/Restore", + "lang_client": "Client", + "lang_clientLog": "Client Log", + "lang_clientStats": "Client statistics", + "lang_configurationBasic": "PXE\/Boot", + "lang_configurationVariables": "Configuration Variables", + "lang_dozmod": "Tutor module", + "lang_eventLog": "Server Log", + "lang_internetAccess": "Internet access", + "lang_language": "Language", + "lang_localization": "Localization", + "lang_locations": "Rooms\/Locations", + "lang_login": "Login", + "lang_logout": "Logout", + "lang_needsSetup": "Setup incomplete", + "lang_news": "vmChooser news", + "lang_server": "Server", + "lang_serverStatus": "Server status", + "lang_settings": "Settings", + "lang_status": "Status", + "lang_translations": "Translations", + "lang_vmLocation": "VM Location", + "lang_warning": "Warning", + "lang_webInterface": "Web interface" +} \ No newline at end of file diff --git a/lang/en/modules/main/messagebox-warning.json b/lang/en/modules/main/messagebox-warning.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lang/en/modules/main/messagebox-warning.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lang/en/modules/main/page-main-guest.json b/lang/en/modules/main/page-main-guest.json new file mode 100644 index 00000000..6526f5bd --- /dev/null +++ b/lang/en/modules/main/page-main-guest.json @@ -0,0 +1,7 @@ +{ + "lang_introGuest": "This is the administration interface of the local bwLehrpool intallation. Please authenticate yourself to adjust settings.", + "lang_login": "Login", + "lang_noExistingAccount": "No account has been created yet. Sign up to become the administrator.", + "lang_register": "Register", + "lang_welcome": "Welcome" +} \ No newline at end of file diff --git a/lang/en/modules/main/page-main.json b/lang/en/modules/main/page-main.json new file mode 100644 index 00000000..8031ac1c --- /dev/null +++ b/lang/en/modules/main/page-main.json @@ -0,0 +1,11 @@ +{ + "lang_bootMenuWarning": "The boot menu is outdated or has not been generated.", + "lang_configure": "Configure", + "lang_intro": "This is the bwLehrpool configuration interface.", + "lang_minilinuxMissing": "Important files from the mini Linux installation are missing.", + "lang_numerOfImagesMarkedForDeletion": "Images marked for deletion", + "lang_systemConfiguration": "System Configuration", + "lang_systemConfigurationNotChosen": "A system configuration has not been chosen yet.", + "lang_vmLocationNotSet": "A location for the virtual machine is not set yet.", + "lang_welcome": "Welcome" +} \ No newline at end of file diff --git a/lang/en/modules/messagebox-error.json b/lang/en/modules/messagebox-error.json new file mode 100644 index 00000000..c44dc44f --- /dev/null +++ b/lang/en/modules/messagebox-error.json @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git a/lang/en/modules/messagebox-info.json b/lang/en/modules/messagebox-info.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lang/en/modules/messagebox-info.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lang/en/modules/messagebox-success.json b/lang/en/modules/messagebox-success.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lang/en/modules/messagebox-success.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lang/en/modules/minilinux/download.json b/lang/en/modules/minilinux/download.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lang/en/modules/minilinux/download.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lang/en/modules/minilinux/filelist.json b/lang/en/modules/minilinux/filelist.json new file mode 100644 index 00000000..89fed42b --- /dev/null +++ b/lang/en/modules/minilinux/filelist.json @@ -0,0 +1,12 @@ +{ + "lang_actual": "Actual", + "lang_canUpdate1": "At least one component of", + "lang_canUpdate2": "can be updated. For a smooth operation, it is recommended to keep all components up to date.", + "lang_configurationPackageNotFound": "Configuration package not found!", + "lang_desiredVersion": "Desired version", + "lang_filesInVersion": "Files for version", + "lang_outdated": "Outdated", + "lang_redownload": "Download again", + "lang_systemUpdated": "The system is up to date.", + "lang_update": "Update" +} \ No newline at end of file diff --git a/lang/en/modules/news/page-news.json b/lang/en/modules/news/page-news.json new file mode 100644 index 00000000..df63658c --- /dev/null +++ b/lang/en/modules/news/page-news.json @@ -0,0 +1,12 @@ +{ + "lang_content": "Content", + "lang_date": "Date", + "lang_delete": "Delete", + "lang_editNews": "Edit news", + "lang_latestUpdate": "Latest update", + "lang_newsIntro": "Here you have the possibility to edit the news displayed to the bwLehrpool clients.", + "lang_newsOld": "Old News", + "lang_save": "Save", + "lang_show": "Show", + "lang_title": "Title" +} \ No newline at end of file diff --git a/lang/en/modules/page-adduser.json b/lang/en/modules/page-adduser.json new file mode 100644 index 00000000..42bae6dc --- /dev/null +++ b/lang/en/modules/page-adduser.json @@ -0,0 +1,8 @@ +{ + "lang_confirmation": "Confirm Password", + "lang_createUser": "Create User", + "lang_fullName": "Full Name", + "lang_password": "Password", + "lang_telephone": "Telephone", + "lang_username": "Username" +} \ No newline at end of file diff --git a/lang/en/modules/page-minilinux.json b/lang/en/modules/page-minilinux.json new file mode 100644 index 00000000..2f59fa57 --- /dev/null +++ b/lang/en/modules/page-minilinux.json @@ -0,0 +1,4 @@ +{ + "lang_errorGetting": "Error while downloading list!", + "lang_listObtained": "Downloading list..." +} \ No newline at end of file diff --git a/lang/en/modules/pagenav.json b/lang/en/modules/pagenav.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lang/en/modules/pagenav.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lang/en/modules/serversetup/ipaddress.json b/lang/en/modules/serversetup/ipaddress.json new file mode 100644 index 00000000..699aeacc --- /dev/null +++ b/lang/en/modules/serversetup/ipaddress.json @@ -0,0 +1,7 @@ +{ + "lang_active": "Active", + "lang_bootAddress": "Boot Address of the Server", + "lang_bootHint": "The Boot menu must be recreated after changing the IP address. Usually this is done automatically, but the process can also be triggered manually in the section of the boot menu.", + "lang_chooseIP": "Please select the IP address that the client server will use to boot.", + "lang_set": "Set" +} \ No newline at end of file diff --git a/lang/en/modules/serversetup/ipxe.json b/lang/en/modules/serversetup/ipxe.json new file mode 100644 index 00000000..70c17f43 --- /dev/null +++ b/lang/en/modules/serversetup/ipxe.json @@ -0,0 +1,31 @@ +{ + "lang_bootBehavior": "Default Boot Behavior", + "lang_bootInfo": "Here adjustments can be made to the appearance of the boot menu.", + "lang_bootMenu": "Boot Menu", + "lang_bootMenuCreate": "Create Boot Menu", + "lang_cancel": "Cancel", + "lang_close": "Close", + "lang_compile": "Compile", + "lang_compilingIpxe": "Compiling iPXE", + "lang_customEntry": "Custom entry", + "lang_customScript": "Custom script", + "lang_download": "Download", + "lang_example": "Example", + "lang_extension": "Extension", + "lang_ipxeInfo": "Here it is possible to compile iPXE using a custom script.", + "lang_ipxeWarning": "If this is your first time compiling, it may take 1 to 4 minutes to finish.", + "lang_loading": "Loading", + "lang_localHDD": "Local HDD", + "lang_masterPassword": "Master password", + "lang_masterPasswordHelp": "The master password is required to edit a boot menu entry. This should be set for security reasons.", + "lang_menuCustom": "Custom Extra Menu", + "lang_menuCustomHint1": "Here you have the opportunity to add your own menu code to the displayed PXE menu, eg to refer to other PXE server. The format corresponds to the syslinux menu format.", + "lang_menuCustomHint2": "You can create one or more entries. If you want to create an entry that starts automatically when the user makes a selection, assign as", + "lang_menuCustomHint3": "and select as the default boot behavior custom as well.", + "lang_menuDisplayTime": "Menu Display Time", + "lang_mountIpxe": "Mount iPXE", + "lang_restoreDefault": "Restore Default", + "lang_saveScript": "Save Script", + "lang_seconds": "Seconds", + "lang_success": "Successfully create file:" +} diff --git a/lang/en/modules/serversetup/ipxe_update.json b/lang/en/modules/serversetup/ipxe_update.json new file mode 100644 index 00000000..b33b12dd --- /dev/null +++ b/lang/en/modules/serversetup/ipxe_update.json @@ -0,0 +1,4 @@ +{ + "lang_generationFailed": "Could not generate boot menu. The bwLehrpool-System might not work properly. If you can't fix the problem, please report the error message above to the bwLehrpool project.", + "lang_menuGeneration": "Generating boot menu..." +} \ No newline at end of file diff --git a/lang/en/modules/session/page-login.json b/lang/en/modules/session/page-login.json new file mode 100644 index 00000000..4b192a7a --- /dev/null +++ b/lang/en/modules/session/page-login.json @@ -0,0 +1,8 @@ +{ + "lang_enter": "Enter", + "lang_login": "Login", + "lang_password": "Password", + "lang_register": "Register", + "lang_rememberID": "Remember ID", + "lang_username": "Username" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/clientlist.json b/lang/en/modules/statistics/clientlist.json new file mode 100644 index 00000000..ae692154 --- /dev/null +++ b/lang/en/modules/statistics/clientlist.json @@ -0,0 +1,14 @@ +{ + "lang_address": "Address", + "lang_clientList": "List of selected machines", + "lang_cpuModel": "CPU", + "lang_gbRam": "RAM", + "lang_kvmSupport": "64\u2009Bit guests", + "lang_lastSeen": "Last seen", + "lang_machine": "Machine", + "lang_machineIdle": "Machine is powered on and is not used", + "lang_machineOccupied": "Machine is powered on and in use", + "lang_machineOff": "Machine is powered down, or is not running bwLehrpool", + "lang_realCores": "Cores", + "lang_tmpGb": "HDD temp" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/cpumodels.json b/lang/en/modules/statistics/cpumodels.json new file mode 100644 index 00000000..864933dd --- /dev/null +++ b/lang/en/modules/statistics/cpumodels.json @@ -0,0 +1,6 @@ +{ + "lang_cpuCores": "CPU cores", + "lang_modelCount": "Count", + "lang_modelName": "Model name", + "lang_modelStats": "PC models" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/id44.json b/lang/en/modules/statistics/id44.json new file mode 100644 index 00000000..0d0081a8 --- /dev/null +++ b/lang/en/modules/statistics/id44.json @@ -0,0 +1,5 @@ +{ + "lang_machineCount": "Count", + "lang_partitionSize": "Size", + "lang_tempPartStats": "Temporary partition" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/kvmstate.json b/lang/en/modules/statistics/kvmstate.json new file mode 100644 index 00000000..b4846473 --- /dev/null +++ b/lang/en/modules/statistics/kvmstate.json @@ -0,0 +1,5 @@ +{ + "lang_kvmState": "State", + "lang_kvmStats": "64\u2009Bit guest support", + "lang_machineCount": "Count" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/machine-hdds.json b/lang/en/modules/statistics/machine-hdds.json new file mode 100644 index 00000000..8ce6801d --- /dev/null +++ b/lang/en/modules/statistics/machine-hdds.json @@ -0,0 +1,13 @@ +{ + "lang_hdds": "Hard disk drives", + "lang_hours": "hours", + "lang_modelNo": "Model", + "lang_partName": "Name", + "lang_partSize": "Size", + "lang_partType": "Type", + "lang_pendingSectors": "Sectors pending reallocation", + "lang_powerOnTime": "Power on time", + "lang_reallocatedSectors": "Bad sectors", + "lang_serialNo": "Serial no", + "lang_total": "Total" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/machine-main.json b/lang/en/modules/statistics/machine-main.json new file mode 100644 index 00000000..1addd437 --- /dev/null +++ b/lang/en/modules/statistics/machine-main.json @@ -0,0 +1,26 @@ +{ + "lang_64bitSupport": "64\u2009Bit guest support", + "lang_cores": "Cores", + "lang_cpuModel": "CPU model", + "lang_firstSeen": "First seen", + "lang_hardwareSummary": "Hardware", + "lang_hostname": "Hostname", + "lang_ip": "IP address", + "lang_lastBoot": "Last boot", + "lang_lastSeen": "Last activity", + "lang_macAddr": "MAC address", + "lang_machineIdle": "Powered on, unused", + "lang_machineOccupied": "Powered on, in use", + "lang_machineOccupiedBy": "In use by", + "lang_machineOff": "bwLehrpool not running", + "lang_machineSummary": "Summary", + "lang_maximumAbbrev": "max.", + "lang_model": "Model", + "lang_ram": "Memory", + "lang_ramSlots": "Memory slots", + "lang_sockets": "Sockets", + "lang_tempPart": "Temp. partition", + "lang_usageState": "State", + "lang_uuid": "UUID", + "lang_virtualCores": "Virtual cores" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/machine-notes.json b/lang/en/modules/statistics/machine-notes.json new file mode 100644 index 00000000..7a13f28a --- /dev/null +++ b/lang/en/modules/statistics/machine-notes.json @@ -0,0 +1,4 @@ +{ + "lang_notes": "Notes", + "lang_save": "Save" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/machine-usage.json b/lang/en/modules/statistics/machine-usage.json new file mode 100644 index 00000000..398996f6 --- /dev/null +++ b/lang/en/modules/statistics/machine-usage.json @@ -0,0 +1,4 @@ +{ + "lang_timebarDesc": "Visual representation of the last few days. Red parts mark periods where the client was occupied, green parts where the client was idle. Dimmed parts mark nights (10pm to 8am).", + "lang_usageDetails": "Detailed usage" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/memory.json b/lang/en/modules/statistics/memory.json new file mode 100644 index 00000000..decdd021 --- /dev/null +++ b/lang/en/modules/statistics/memory.json @@ -0,0 +1,5 @@ +{ + "lang_machineCount": "Count", + "lang_memoryStats": "Memory", + "lang_ramSize": "Size" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/newclients.json b/lang/en/modules/statistics/newclients.json new file mode 100644 index 00000000..f7e55f3f --- /dev/null +++ b/lang/en/modules/statistics/newclients.json @@ -0,0 +1,4 @@ +{ + "lang_machine": "Client", + "lang_newMachines": "New machines" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/summary.json b/lang/en/modules/statistics/summary.json new file mode 100644 index 00000000..b57c290f --- /dev/null +++ b/lang/en/modules/statistics/summary.json @@ -0,0 +1,6 @@ +{ + "lang_inUseMachines": "In use", + "lang_knownMachines": "Known clients", + "lang_onlineMachines": "Online clients", + "lang_withBadSectors": "Clients with potentially bad HDDs (more than 10 reallocated sectors)" +} \ No newline at end of file diff --git a/lang/en/modules/statistics/syslog.json b/lang/en/modules/statistics/syslog.json new file mode 100644 index 00000000..6737ca68 --- /dev/null +++ b/lang/en/modules/statistics/syslog.json @@ -0,0 +1,7 @@ +{ + "lang_details": "Details", + "lang_event": "Event", + "lang_logHeadline": "Logging", + "lang_more": "More", + "lang_when": "When" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/_page.json b/lang/en/modules/sysconfig/_page.json new file mode 100644 index 00000000..6f139359 --- /dev/null +++ b/lang/en/modules/sysconfig/_page.json @@ -0,0 +1,28 @@ +{ + "lang_activate": "Activate", + "lang_active": "Active", + "lang_availableModules": "Available Configuration Modules", + "lang_availableSystem": "Available System Configuration", + "lang_close": "Close", + "lang_configurationModuleNotFound": "Configuration module not found!", + "lang_delete": "Delete", + "lang_deleteLong": "Delete module or configuration.", + "lang_download": "Download", + "lang_downloadLong": "Download module \"as is\".", + "lang_edit": "Edit", + "lang_editLong": "Edit module or configuration.", + "lang_helpModuleConfiguration": "Configuration modules are the building blocks from which a system configuration is created. Here you can create both generic modules by a wizard, as well as create completely custom modules (advanced Linux knowledge required).", + "lang_helpSystemConfiguration": "The fundamental localization of the bwLehrpool system is done through a system configuration. These include aspects such as the authentication method for users (eg Active Directory, LDAP), printer configuration, home directories, etc. A system configuration is composed of one or more configuration modules, which can be managed in the panel next to this one.", + "lang_legend": "Legend", + "lang_moduleConfiguration": "Module Configuration", + "lang_newConfiguration": "New Configuration", + "lang_newModule": "New Module", + "lang_rebuild": "Rebuild", + "lang_rebuildLong": "Rebuild module or configuration.", + "lang_rebuildOutdatedLong": "Rebuild module or configuration. The module\/configuration is outdated or missing and should be regenerated.", + "lang_show": "Show", + "lang_showLong": "Show content of module.", + "lang_systemConfiguration": "System Configuration", + "lang_systemConfigurationAlert": "Before you can create a system configuration, you must first create a configuration module.", + "lang_systemConfigurationNotFound": "No system configurations found. Create a new configuration from the configuration modules listed below." +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ad-finish.json b/lang/en/modules/sysconfig/ad-finish.json new file mode 100644 index 00000000..8f89046e --- /dev/null +++ b/lang/en/modules/sysconfig/ad-finish.json @@ -0,0 +1,7 @@ +{ + "lang_adStarted": "The AD-proxy is now configured and started ...", + "lang_generateModule": "Generate Module", + "lang_restartWizard": "Restart Wizard", + "lang_systemConfiguration": "System Configuration", + "lang_to": "To" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ad-selfsearch.json b/lang/en/modules/sysconfig/ad-selfsearch.json new file mode 100644 index 00000000..70db0620 --- /dev/null +++ b/lang/en/modules/sysconfig/ad-selfsearch.json @@ -0,0 +1,10 @@ +{ + "lang_back": "Back", + "lang_continueAnyway": "Continue anyway", + "lang_dnLookup": "Looking up bind dn", + "lang_homeAttributeExplanation": "Please select the attribute which holds the user's home directory.", + "lang_next": "Next", + "lang_onProblemSearchBase": "On failure, try to pass the bind dn and search base manually", + "lang_selectHomeAttribute": "Home attribute", + "lang_skip": "Skip" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ad-start.json b/lang/en/modules/sysconfig/ad-start.json new file mode 100644 index 00000000..ff35fc03 --- /dev/null +++ b/lang/en/modules/sysconfig/ad-start.json @@ -0,0 +1,23 @@ +{ + "lang_adText1": "To set up user authentication through Active Directory, a dedicated user is required in AD next to the address of the server, which is addressed by the AD.", + "lang_adText2": "This user does not need special rights, you can follow this user to evade security and the rights to log on. The user only needs to have sufficient permissions to perform an LDAP Bind on AD, and search for users.", + "lang_adText3": "Next the distinguished name of the user must be specified. You can determine this by dsquery command line program on a domain controller as the following call:", + "lang_adText4": "After entering all required data in the next step, it checks whether communication is possible with the AD.", + "lang_asteriskMandatory": "Fields marked with (*) are mandatory", + "lang_bindDN": "Bind DN", + "lang_close": "Close", + "lang_customCertificate": "Additional (intermediate) certificates required for certificate validation", + "lang_helpHomeAttrHead": "Name of the home directory attribute", + "lang_helpHomeAttrText": "Here you can specify the name of the attribute on the Active Directory that contains the path of the home directory server. Usually this is \"homeDirectory\". If you leave this blank, the wiszard will try to determine the attribute name automatically. If home directories don't work, check the client log (Status->Client log) and the LDAP proxy log (Status->Server status).", + "lang_homeAttr": "Home attribute", + "lang_moduleTitle": "Title", + "lang_next": "Next", + "lang_password": "Password", + "lang_searchBase": "Search Base", + "lang_ssl": "SSL", + "lang_sslDescription": "Use SSL encryption to talk to AD server.", + "lang_userDirectory": "User Directory", + "lang_userDirectoryInfo1": "Optional: If the clients should embed a separate directory (home directory, user directory) from a server for the user, please enter here the format in UNC notation, eg", + "lang_userDirectoryInfo2": "%s is a placeholder for the user's login name.", + "lang_userDirectoryInfo3": "The directory is loaded with the same credentials that the user specifies when login. (That is no Kerberos support, etc.)" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ad_ldap-checkconnection.json b/lang/en/modules/sysconfig/ad_ldap-checkconnection.json new file mode 100644 index 00000000..6a924f8b --- /dev/null +++ b/lang/en/modules/sysconfig/ad_ldap-checkconnection.json @@ -0,0 +1,8 @@ +{ + "lang_back": "Back", + "lang_connectionWait": "Checking connection...", + "lang_next": "Next", + "lang_noOpenPort": "There is no open LDAP port on this server.", + "lang_noValidCert": "The server did not supply a certificate, or the certificate is invalid.", + "lang_selfSignedNote": "The certificate of this server cannot be verified using the builtin trust store. If you know that the server's certificate was signed by an unknown CA, you can try to proceed. The chain will then be extracted from the server, which should be successful in most cases. If the authentication module does not work afterwards, check the LDAP-proxy logs on the server status page." +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ad_ldap-checkcredentials.json b/lang/en/modules/sysconfig/ad_ldap-checkcredentials.json new file mode 100644 index 00000000..2b83a231 --- /dev/null +++ b/lang/en/modules/sysconfig/ad_ldap-checkcredentials.json @@ -0,0 +1,6 @@ +{ + "lang_back": "Back", + "lang_connectionWait": "The connection to the specified AD server is now checked. Please wait a moment.", + "lang_onProblemSearchBase": "If this step fails and you didn't supply a search base, try again with a valid one.", + "lang_skip": "Skip" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ad_ldap-homedir.json b/lang/en/modules/sysconfig/ad_ldap-homedir.json new file mode 100644 index 00000000..90d4a211 --- /dev/null +++ b/lang/en/modules/sysconfig/ad_ldap-homedir.json @@ -0,0 +1,18 @@ +{ + "lang_folderRedirection": "Folder Redirection", + "lang_handlingNotes": "Here you can configure how network shares (like the user's home directory) are mapped inside the VM. Old Versions of bwLehrpool used the VMware Shared Folder technique, which could cause problems with certain file servers. The new \"native mode\" works much better, but on Windows guests, it requires that you (1) use an smb\/cifs file server (Windows Server, Linux with Samba) and (2) have openslx.exe setup to autorun in the VM (this is already configured for bwLehrpool templates). Native mode with fallback is experimental and known to cause temporary freezes with some VMs. Use with care. IMPORTANT: Pick a drive letter for the home directory that will be free in the Virtual Machines. Otherwise, a random letter will be assigned.", + "lang_homedirHandling": "(Home) directory handling", + "lang_mapModeNative": "Natively map inside the VM [openslx.exe]", + "lang_mapModeNativeFallback": "Natively map inside VM; fallback to VMware Shared Folders", + "lang_mapModeNone": "Don't map shares at all", + "lang_mapModeVmware": "VMware Shared Folders [VMwareTools]", + "lang_redirectionWarning": "WARNING: This feature is experimental. It remaps the selected folders after the VM booted (via openslx.exe) to the logged in user's home drive. This might cause problems with applications that start before the pathes are patched, as they will see the old unpatched settings. This also doesn't work fully on Windows 10. If you want to reliably remap these directories, it's recommended to change their locations in the VM before uploading it.", + "lang_shareDesktop": "Desktop (Might hide shortcuts created by the tutor)", + "lang_shareDocuments": "My Documents", + "lang_shareDownloads": "Downloads", + "lang_shareHomeDrive": "Home drive letter (Windows)", + "lang_shareMapCreate": "Create folders on network share if they don't exist", + "lang_shareMedia": "My Music, Videos, Pictures", + "lang_shareOther": "Other (Saved Games, Contacts, Favorites, ...)", + "lang_shareRemapMode": "Mapping mode" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/branding-check.json b/lang/en/modules/sysconfig/branding-check.json new file mode 100644 index 00000000..6a481d8b --- /dev/null +++ b/lang/en/modules/sysconfig/branding-check.json @@ -0,0 +1,5 @@ +{ + "lang_brandingInfo": "Below you can check the selected logo. If you can not see the logo, please check whether you have used a valid SVG image. Alternatively, it is possible that during processing of the image, an error occurred. Therefore, you can save the module anyway and test whether the logo is displayed in the bwLehrpool system.", + "lang_save": "Save", + "lang_title": "Title" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/branding-start.json b/lang/en/modules/sysconfig/branding-start.json new file mode 100644 index 00000000..4423784d --- /dev/null +++ b/lang/en/modules/sysconfig/branding-start.json @@ -0,0 +1,9 @@ +{ + "lang_branding": "For best results, you should upload the logo in SVG format. SVG is a vector graphics format, which is advantageous for scaling. A good source for SVG logos of universities and colleges is their respective Wikipedia article.", + "lang_browseForFile": "Browse", + "lang_computerLoad": "Load image from local computer", + "lang_or": "or", + "lang_selectFile": "Please select a file", + "lang_upload": "Upload", + "lang_urlLoad": "Load image from URL" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/cfg-finish.json b/lang/en/modules/sysconfig/cfg-finish.json new file mode 100644 index 00000000..b8729636 --- /dev/null +++ b/lang/en/modules/sysconfig/cfg-finish.json @@ -0,0 +1,4 @@ +{ + "lang_configurationActive": "Enable configuration", + "lang_configurationSuccess": "The configuration has been successfully created." +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/cfg-start.json b/lang/en/modules/sysconfig/cfg-start.json new file mode 100644 index 00000000..9afc6ce3 --- /dev/null +++ b/lang/en/modules/sysconfig/cfg-start.json @@ -0,0 +1,6 @@ +{ + "lang_configuration": "Configuration", + "lang_configurationChoose": "Please select which modules will be used for this configuration.", + "lang_name": "Name", + "lang_noModuleOfType": "No module of this type found." +} diff --git a/lang/en/modules/sysconfig/config-module-list.json b/lang/en/modules/sysconfig/config-module-list.json new file mode 100644 index 00000000..ff30c0b4 --- /dev/null +++ b/lang/en/modules/sysconfig/config-module-list.json @@ -0,0 +1,4 @@ +{ + "lang_noContent": "No content!", + "lang_show": "Show" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/custom-filelist.json b/lang/en/modules/sysconfig/custom-filelist.json new file mode 100644 index 00000000..50bec5b5 --- /dev/null +++ b/lang/en/modules/sysconfig/custom-filelist.json @@ -0,0 +1,3 @@ +{ + "lang_back": "Back" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/custom-fileselect.json b/lang/en/modules/sysconfig/custom-fileselect.json new file mode 100644 index 00000000..2ae25e16 --- /dev/null +++ b/lang/en/modules/sysconfig/custom-fileselect.json @@ -0,0 +1,5 @@ +{ + "lang_checkFileContent": "Here you have the possibility to check the contents of the archive again.", + "lang_moduleName": "Module Name", + "lang_next": "Next" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/custom-upload.json b/lang/en/modules/sysconfig/custom-upload.json new file mode 100644 index 00000000..26b7c186 --- /dev/null +++ b/lang/en/modules/sysconfig/custom-upload.json @@ -0,0 +1,8 @@ +{ + "lang_browseForFile": "Browse", + "lang_customModuleInfo1": "About a custom module, it is possible to add arbitrary files to a Linux system that is booted clients. For this purpose, an archive can be uploaded using a file system structure that is extracted in this form 1:1 in the booted Linux.", + "lang_customModuleInfo2": "Example: If the uploaded archive is the file etc\/example.conf, this file will be located as \/etc\/example.conf to a booted client.", + "lang_selectFile": "Please select an archive", + "lang_supportedFiles": "Supported File Formats", + "lang_upload": "Upload" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ldap-checkconnection.json b/lang/en/modules/sysconfig/ldap-checkconnection.json new file mode 100644 index 00000000..52fbae9e --- /dev/null +++ b/lang/en/modules/sysconfig/ldap-checkconnection.json @@ -0,0 +1,5 @@ +{ + "lang_back": "Back", + "lang_connectionWait": "Checking connection, please wait", + "lang_next": "Next" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ldap-checkcredentials.json b/lang/en/modules/sysconfig/ldap-checkcredentials.json new file mode 100644 index 00000000..2a8723c9 --- /dev/null +++ b/lang/en/modules/sysconfig/ldap-checkcredentials.json @@ -0,0 +1,6 @@ +{ + "lang_back": "Back", + "lang_connectionWait": "Checking LDAP credentials", + "lang_onProblemSearchBase": "If no users are found, please check the search base", + "lang_skip": "Next" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ldap-finish.json b/lang/en/modules/sysconfig/ldap-finish.json new file mode 100644 index 00000000..bd15bafc --- /dev/null +++ b/lang/en/modules/sysconfig/ldap-finish.json @@ -0,0 +1,6 @@ +{ + "lang_generateModule": "Generating module", + "lang_ldapStarted": "The LDAP proxy has been launched", + "lang_restartWizard": "Restart wizard", + "lang_toSystemConfiguration": "Go to system configuration" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/ldap-start.json b/lang/en/modules/sysconfig/ldap-start.json new file mode 100644 index 00000000..45ba19f1 --- /dev/null +++ b/lang/en/modules/sysconfig/ldap-start.json @@ -0,0 +1,16 @@ +{ + "lang_bindDN": "Bind domain", + "lang_close": "Close", + "lang_customCertificate": "Additional (intermediate) certificates required for certificate validation", + "lang_ldapText1": "Here you can create a configuration module to authenticate agains an LDAP server", + "lang_ldapText2": "An LDAP-Proxy will be launched on this server. This means the LDAP-Server must be reachable from it. The client PCs in the labs however don't have to be able to talk to the LDAP server \u2013 they will use the proxy running on this server.", + "lang_moduleTitle": "Module name", + "lang_next": "Next", + "lang_password": "Password", + "lang_searchBase": "Search base", + "lang_ssl": "SSL", + "lang_sslDescription": "Use SSL to connect to the LDAP-Server. (The connection between clients and proxy uses SSL in either case.) Some LDAP servers require SSL for authenticating connections.", + "lang_userDirectory": "Home-Directory", + "lang_userDirectoryInfo1": "UNC-path to home directory of user. '%s' can be used as a placeholder for the account name.", + "lang_userDirectoryInfo2": "Currently, only CIFS\/SMB is supported." +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/sshconfig-start.json b/lang/en/modules/sysconfig/sshconfig-start.json new file mode 100644 index 00000000..1ce553cd --- /dev/null +++ b/lang/en/modules/sysconfig/sshconfig-start.json @@ -0,0 +1,10 @@ +{ + "lang_allowPass": "Allow password login", + "lang_allowPassInfo": "When active, logins via username and password are allowed. Otherwise, only pubkey authentication is possible.", + "lang_listenPort": "Listen port", + "lang_listenPortInfo": "Listen port for the sshd. Default is 22.", + "lang_moduleName": "Module name", + "lang_rootKey": "root pubkey", + "lang_rootKeyInfo": "Here you can add the public key of a keypair that you want to use for authentication as root-user. Leave this field blank to disable the feature.", + "lang_save": "Save" +} \ No newline at end of file diff --git a/lang/en/modules/sysconfig/start.json b/lang/en/modules/sysconfig/start.json new file mode 100644 index 00000000..4567d649 --- /dev/null +++ b/lang/en/modules/sysconfig/start.json @@ -0,0 +1,4 @@ +{ + "lang_add": "Add", + "lang_moduleChoose": "Please select which type of configuration module you want to create." +} \ No newline at end of file diff --git a/lang/en/modules/syslog/page-syslog.json b/lang/en/modules/syslog/page-syslog.json new file mode 100644 index 00000000..71f61693 --- /dev/null +++ b/lang/en/modules/syslog/page-syslog.json @@ -0,0 +1,10 @@ +{ + "lang_client": "Client", + "lang_clientLog": "Client Log", + "lang_details": "Details", + "lang_event": "Event", + "lang_filter": "Filter", + "lang_go": "Go", + "lang_not": "not", + "lang_when": "When" +} \ No newline at end of file diff --git a/lang/en/modules/systemstatus/_page.json b/lang/en/modules/systemstatus/_page.json new file mode 100644 index 00000000..f698521d --- /dev/null +++ b/lang/en/modules/systemstatus/_page.json @@ -0,0 +1,11 @@ +{ + "lang_addressConfiguration": "Address Configuration", + "lang_advanced": "Advanced \/ Debug", + "lang_dmsdLog": "dmsd log", + "lang_iAmSure": "Yes, I am sure", + "lang_ldadpLog": "AD\/LDAP proxy log", + "lang_maintenance": "Maintenance", + "lang_services": "Services", + "lang_space": "Space", + "lang_system": "System" +} \ No newline at end of file diff --git a/lang/en/modules/systemstatus/addresses.json b/lang/en/modules/systemstatus/addresses.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lang/en/modules/systemstatus/addresses.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lang/en/modules/systemstatus/diskstat.json b/lang/en/modules/systemstatus/diskstat.json new file mode 100644 index 00000000..6c880ebe --- /dev/null +++ b/lang/en/modules/systemstatus/diskstat.json @@ -0,0 +1,12 @@ +{ + "lang_capacity": "Capacity", + "lang_foundStore": "Found:", + "lang_free": "Free", + "lang_goToStoreConf": "Go to VM store configuration", + "lang_storeMissingExpected": "VM store not mounted. Expected:", + "lang_storeNotConfigured": "No VM store configured!", + "lang_systemPartition": "System Partition", + "lang_systemStoreError": "Error querying available system storage", + "lang_vmStore": "VM Store", + "lang_vmStoreError": "Error determining available space of the VM storage. Please check the configuration." +} \ No newline at end of file diff --git a/lang/en/modules/systemstatus/services.json b/lang/en/modules/systemstatus/services.json new file mode 100644 index 00000000..2c63c085 --- /dev/null +++ b/lang/en/modules/systemstatus/services.json @@ -0,0 +1,2 @@ +{ +} diff --git a/lang/en/modules/systemstatus/systeminfo.json b/lang/en/modules/systemstatus/systeminfo.json new file mode 100644 index 00000000..602693f5 --- /dev/null +++ b/lang/en/modules/systemstatus/systeminfo.json @@ -0,0 +1,15 @@ +{ + "lang_attention": "Attention!", + "lang_average": "Average", + "lang_cpuLoad": "CPU Load", + "lang_free": "Free", + "lang_logicCPUs": "Logic CPUs", + "lang_notDetermined": "Could not be determined", + "lang_occupied": "Occupied", + "lang_onlyOS": "OS Only", + "lang_ramUsage": "RAM Usage", + "lang_swapUsage": "swap Usage", + "lang_swapWarning": "Memory swap is being used. This may be an indication that the satellite server does not have enough physical memory available. In the case of performance problems or server instability you should consider equipping the server with more RAM.", + "lang_total": "Total", + "lang_uptimeOS": "OS Uptime" +} \ No newline at end of file diff --git a/lang/en/modules/translation/_page.json b/lang/en/modules/translation/_page.json new file mode 100644 index 00000000..5a48b696 --- /dev/null +++ b/lang/en/modules/translation/_page.json @@ -0,0 +1,9 @@ +{ + "lang_adminInfo": "In this section you can change the JSON tags that contains the translated texts used by the site. To do this, select a template below to modify their respective tags. Alternatively, click the link below to change the messages of the site.", + "lang_editConfigModule": "Edit config module strings", + "lang_editHardcoded": "Edit hardcoded strings", + "lang_editMessages": "Edit Messages", + "lang_editSettings": "Edit configuration variables related strings", + "lang_editTemplates": "Edit template strings", + "lang_langAdministration": "Language Administration" +} \ No newline at end of file diff --git a/lang/en/modules/translation/edit.json b/lang/en/modules/translation/edit.json new file mode 100644 index 00000000..05c6697a --- /dev/null +++ b/lang/en/modules/translation/edit.json @@ -0,0 +1,12 @@ +{ + "lang_back": "Back", + "lang_createTag": "Create TAG", + "lang_deleteTAG": "Delete", + "lang_englishTAG": "English TAG", + "lang_germanTAG": "German TAG", + "lang_newTAG": "New TAG", + "lang_portugueseTAG": "Portuguese TAG", + "lang_save": "Save", + "lang_templateAdminHelp": "Here you can translate and edit phrases and texts.", + "lang_templateHint": "Hint: Yellow lines indicate a translation is missing and red lines indicate a tag is not being used by the template." +} \ No newline at end of file diff --git a/lang/en/modules/translation/template-list.json b/lang/en/modules/translation/template-list.json new file mode 100644 index 00000000..e3feb70b --- /dev/null +++ b/lang/en/modules/translation/template-list.json @@ -0,0 +1,5 @@ +{ + "lang_adminInfo": "This is a list of all templates. The \u0022status\u0022-column tells if there are translations missing, or unused tags are defined.", + "lang_langAdministration": "Templates", + "lang_status": "Status" +} \ No newline at end of file diff --git a/lang/en/modules/usermanagement/user-management.json b/lang/en/modules/usermanagement/user-management.json new file mode 100644 index 00000000..61225f55 --- /dev/null +++ b/lang/en/modules/usermanagement/user-management.json @@ -0,0 +1,18 @@ +{ + "lang_cancelConfirm": "Do you really want to delete this users?", + "lang_close": "Close", + "lang_create": "Create", + "lang_edit": "Edit", + "lang_editUser": "Edit User", + "lang_email": "Email", + "lang_login": "Login", + "lang_operations": "Operation", + "lang_password": "Password", + "lang_remove": "Remove", + "lang_save": "Save", + "lang_telephone": "Telephone", + "lang_userAdmin": "Administrator", + "lang_userInfo": "On this section, you will be able to create website users, besides editing or removing existing users.", + "lang_userPage": "Users", + "lang_username": "Username" +} \ No newline at end of file diff --git a/lang/en/modules/vmstore/mount.json b/lang/en/modules/vmstore/mount.json new file mode 100644 index 00000000..29814430 --- /dev/null +++ b/lang/en/modules/vmstore/mount.json @@ -0,0 +1,5 @@ +{ + "lang_back": "Back", + "lang_configure": "Configure", + "lang_vmLocationConfiguration": "VM location is configured" +} \ No newline at end of file diff --git a/lang/en/modules/vmstore/page-vmstore.json b/lang/en/modules/vmstore/page-vmstore.json new file mode 100644 index 00000000..23ddbbd3 --- /dev/null +++ b/lang/en/modules/vmstore/page-vmstore.json @@ -0,0 +1,17 @@ +{ + "lang_close": "Close", + "lang_intern": "Intern", + "lang_nfsHelp1": "An NFSv4\/3-Share is required. It should be readable by all the workstations, and writable for the satellite server. An example, assuming the satellite server has IP address 1.2.3.4:", + "lang_nfsHelp2": "Alternate configuration using all_squash. The exported directory should be owned (and be writable) by the user with uid 1234.", + "lang_noAdditionalInformation": "No additional cofiguration required", + "lang_password": "Password", + "lang_readOnly": "Read-only Access", + "lang_readWrite": "Read\/Write Access", + "lang_save": "Save", + "lang_username": "Username", + "lang_vmLocation": "VM Location", + "lang_vmLocationChoose": "Please choose where the images of virtual machines will be stored.", + "lang_vmLocationHelp1": "For test purposes, the VMs can be stored directly on the Satellite server. However, if you operate the delivered satellite vmdk please remember that you have only about 100GB of memory.", + "lang_vmLocationHelp2": "In productive operation, it makes sense for this to use a high-performance network storage. This network storage can be integrated via NFS or CIFS \/ SMB. In any case, it must be ensured that the satellite server has write access to this network storage to add a new Virtual Machine . When using NFSv3 this can be set up IP-based, for the use of CIFS \/ SMB, you can access data disclosures that would entitle them to write.", + "lang_vmLocationHelp3": "The bwLehrpool clients only need read access to the network storage (and for security reasons, really can only read). In CIFS \/ SMB You can do this most easily by allowing passwordless guest access with read access to the share." +} \ No newline at end of file diff --git a/lang/en/modules/webinterface/httpd-restart.json b/lang/en/modules/webinterface/httpd-restart.json new file mode 100644 index 00000000..0a7d4aea --- /dev/null +++ b/lang/en/modules/webinterface/httpd-restart.json @@ -0,0 +1,4 @@ +{ + "lang_applyingSettings": "Applying settings", + "lang_installAndRestart": "Installing certificate and restarting web server" +} \ No newline at end of file diff --git a/lang/en/modules/webinterface/https.json b/lang/en/modules/webinterface/https.json new file mode 100644 index 00000000..64631a9a --- /dev/null +++ b/lang/en/modules/webinterface/https.json @@ -0,0 +1,12 @@ +{ + "lang_HttpsIsDisabled": "HTTPS is currently disabled", + "lang_caChain": "Here you can paste an optional certificate chain. It should only be required if you have a certificate that was not directly signed by a certificate authority known by the browsers. It should contain one or more certificate blocks, looking just like the certificate above.", + "lang_certificate": "Please paste your certificate below. It has to be in base64 encoded x509 format (sometimes called pem). It should look something like this:", + "lang_customCert": "Supply own certificate", + "lang_description": "Here you can set whether the web interface should be accessible via https. You can chose if you want to use a random self signed certificate, or supply your own.", + "lang_httpsSettings": "HTTPS settings", + "lang_noHttps": "Disable HTTPS, delete current certificate", + "lang_privateKey": "Please paste the private key belonging to the certificate here. It has to be in \"pem\" format too, which should look like this:", + "lang_randomCert": "Genenrate new self-signed certificate", + "lang_save": "Save" +} \ No newline at end of file diff --git a/lang/en/modules/webinterface/passwords.json b/lang/en/modules/webinterface/passwords.json new file mode 100644 index 00000000..2db88ae2 --- /dev/null +++ b/lang/en/modules/webinterface/passwords.json @@ -0,0 +1,7 @@ +{ + "lang_description": "Set whether password fields should be masked or not. The password field of the login page to the web interface is always masked.", + "lang_hidePasswords": "Mask passwords", + "lang_passwordFields": "Password fields", + "lang_save": "Save", + "lang_showPasswords": "Show passwords" +} \ No newline at end of file diff --git a/lang/en/templates/backup/_page.json b/lang/en/templates/backup/_page.json deleted file mode 100644 index 799c6168..00000000 --- a/lang/en/templates/backup/_page.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "lang_backup": "Backup", - "lang_backupDescription": "Here you can backup the complete configuration of this satellite server. This includes lecture and virtual machine meta data. The HDD images of the virtual machines on the vm store are not included in this backup, because of their size. If desired, the store needs to be backed up manually.", - "lang_backupRestore": "Backup and restore", - "lang_browseForFile": "Browse", - "lang_download": "Download", - "lang_dozmodExplanation": "This restores all the virtual machine and lecture meta data created using the \"Dozentenmodul\". Please make sure the VM-storage configured still contains all the VM-Images associated with the virtual machines. If the location of the storage changed, make sure the relative pathes on the share are still the same, otherwise the virtual machines won't be usable.", - "lang_restore": "Upload", - "lang_restoreDescription": "Here you can restore a configuration backup. Please note that this will reboot the server, so it is advised to do this while nobody is using the system. Please note that this will also restore the password for the web interface that was active when the configuration backup was created.", - "lang_restoreDozmodConfig": "Restore Dozentenmodul config", - "lang_restoreSystemConfig": "Restore system config", - "lang_selectFile": "Please select a backup archive", - "lang_systemExplanation": "Restore basic configuration like authentication method, passwords, vm storage location, proxy config, etc. WARNING: If you restore a configuration backup that was made before WS15\/16 (backup format version <10), the system configuration will be restored regardless of this check mark." -} \ No newline at end of file diff --git a/lang/en/templates/backup/restore.json b/lang/en/templates/backup/restore.json deleted file mode 100644 index 5a5f6f64..00000000 --- a/lang/en/templates/backup/restore.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "lang_backup": "Backup...", - "lang_reboot": "System reboot", - "lang_restoreConfig": "Restore config", - "lang_restoreFailed": "Restoring configuration failed.", - "lang_stopping": "Stopping", - "lang_waitReboot": "Waiting for reboot." -} \ No newline at end of file diff --git a/lang/en/templates/baseconfig/_page.json b/lang/en/templates/baseconfig/_page.json deleted file mode 100644 index 6429a835..00000000 --- a/lang/en/templates/baseconfig/_page.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_basicConfiguration": "Basic Configuration", - "lang_clientRelatedConfig": "The options on this page are related to the bwLehrpool client machines.", - "lang_close": "Close", - "lang_reset": "Reset", - "lang_save": "Save" -} \ No newline at end of file diff --git a/lang/en/templates/dialog-generic.json b/lang/en/templates/dialog-generic.json deleted file mode 100644 index c7551ed3..00000000 --- a/lang/en/templates/dialog-generic.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "lang_next": "Next" -} \ No newline at end of file diff --git a/lang/en/templates/dozmod/images-delete.json b/lang/en/templates/dozmod/images-delete.json deleted file mode 100644 index fcc8c7e7..00000000 --- a/lang/en/templates/dozmod/images-delete.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lang_delButton": "Permanently delete selected images", - "lang_delete": "Delete", - "lang_description": "This list shows images that reached their expire date, or where the image file in the file system is damaged or missing. You need to manually confirm the deletion of these files for safety reasons (software bugs, wrong system time, etc.).", - "lang_hasNewer": "Newer version exists", - "lang_heading": "Images marked for deletion", - "lang_image": "VM", - "lang_owner": "Owner", - "lang_size": "Size", - "lang_subHeading": "Expired or damaged images", - "lang_version": "Version timestamp" -} \ No newline at end of file diff --git a/lang/en/templates/dozmod/mailconfig.json b/lang/en/templates/dozmod/mailconfig.json deleted file mode 100644 index 0c0dcd7f..00000000 --- a/lang/en/templates/dozmod/mailconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "lang_asteriskRequired": "Fields marked with (*) are required", - "lang_host": "Host", - "lang_mailConfig": "SMTP configuration for sending mails", - "lang_mailConfigHeadline": "email configuration", - "lang_mailDescription": "Fill in the following fields if you want to notify tutors\/professors\/lecturers about expiring VMs and lectures. If you leave one of the required fields blank, the feature will be disabled.", - "lang_password": "Password", - "lang_port": "Port", - "lang_replyTo": "Reply-To address", - "lang_save": "Save configuration", - "lang_senderAddress": "Sender address", - "lang_senderName": "Sender's display name", - "lang_ssl": "SSL mode", - "lang_sslExplicit": "Explicit SSL (\"STARTTLS\")", - "lang_sslImplicit": "Implicit SSL", - "lang_sslNone": "No SSL", - "lang_test": "Send test mail", - "lang_testConfiguration": "To test the configuration, enter a recipient address here", - "lang_testRecipient": "Recipient", - "lang_username": "User name (SMTP auth)" -} \ No newline at end of file diff --git a/lang/en/templates/dozmod/orglist.json b/lang/en/templates/dozmod/orglist.json deleted file mode 100644 index 37b89e02..00000000 --- a/lang/en/templates/dozmod/orglist.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lang_canLogin": "Members of this organization can login", - "lang_organization": "Organization", - "lang_organizationList": "List of organizations", - "lang_organizationListHeader": "Set access permissions for organizations" -} \ No newline at end of file diff --git a/lang/en/templates/dozmod/userlist.json b/lang/en/templates/dozmod/userlist.json deleted file mode 100644 index 615f1b14..00000000 --- a/lang/en/templates/dozmod/userlist.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lang_canLogin": "This user can login to this satellite", - "lang_email": "E-Mail", - "lang_emailNotifications": "E-Mail notifications enabled", - "lang_lastLogin": "Last login", - "lang_organization": "Organization", - "lang_superUser": "Is super user (can edit\/delete all lectures and VMs)", - "lang_user": "User name", - "lang_userList": "User list", - "lang_userListDescription": "Here you can promote \"super users\", which will have all permissions in the \"Dozenzenmodul\". You can also ban users from accessing this server via the \"Dozentenmodul\".", - "lang_userListHeader": "Users known to this satellite" -} \ No newline at end of file diff --git a/lang/en/templates/eventlog/_page.json b/lang/en/templates/eventlog/_page.json deleted file mode 100644 index 21ec64ea..00000000 --- a/lang/en/templates/eventlog/_page.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lang_details": "Details", - "lang_event": "Event", - "lang_eventLog": "Event log", - "lang_when": "When" -} \ No newline at end of file diff --git a/lang/en/templates/internetaccess/_page.json b/lang/en/templates/internetaccess/_page.json deleted file mode 100644 index c02ca4f5..00000000 --- a/lang/en/templates/internetaccess/_page.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "lang_automatic": "Auto", - "lang_description": "Here you can configure how the satellite server has to access the internet.", - "lang_internetAccess": "Internet access", - "lang_manual": "Manual", - "lang_manualProxyConfig": "If you want to configure a proxy server manually, please supply the credentials here.", - "lang_no": "None", - "lang_proxyAddress": "Address", - "lang_proxyPassword": "Password", - "lang_proxyPort": "Port", - "lang_proxyType": "Proxy type", - "lang_proxyUsername": "User", - "lang_save": "Save" -} \ No newline at end of file diff --git a/lang/en/templates/internetaccess/restart.json b/lang/en/templates/internetaccess/restart.json deleted file mode 100644 index badad460..00000000 --- a/lang/en/templates/internetaccess/restart.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_restartFailed": "Restarting one or more services failed!", - "lang_restarting": "Restarting", - "lang_serviceRestart": "Restart of services" -} \ No newline at end of file diff --git a/lang/en/templates/locations/location-subnets.json b/lang/en/templates/locations/location-subnets.json deleted file mode 100644 index 2ba94384..00000000 --- a/lang/en/templates/locations/location-subnets.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "lang_addNewSubnet": "Add new subnet", - "lang_assignSubnetExplanation": "Client machines which fall into an IP range listed below will be assigned to this location and will see an according lecture list (e.g. they will see lectures that are exclusively assigned to this location).", - "lang_assignedSubnets": "Assigned subnets \/ IP ranges", - "lang_deleteChildLocations": "Delete child locations aswell", - "lang_deleteLocation": "Delete location", - "lang_deleteSubnet": "Delete range", - "lang_endAddress": "End address", - "lang_locationInfo": "Location details", - "lang_locationSettings": "Edit this room or location", - "lang_matchingMachines": "Matching clients", - "lang_name": "Name", - "lang_parentLocation": "Parent location", - "lang_referencingLectures": "Assigned Lectures", - "lang_save": "Save", - "lang_startAddress": "Start address", - "lang_subnet": "IP range" -} \ No newline at end of file diff --git a/lang/en/templates/locations/locations.json b/lang/en/templates/locations/locations.json deleted file mode 100644 index db4fd0a7..00000000 --- a/lang/en/templates/locations/locations.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "lang_areYouSureNoUndo": "Are you sure? This cannot be undone!", - "lang_edit": "Edit", - "lang_location": "Ort", - "lang_locationName": "Name", - "lang_locationsMainHeading": "Manage rooms and locations", - "lang_noParent": "No parent", - "lang_save": "Save", - "lang_thisListBySubnet": "List by subnet" -} \ No newline at end of file diff --git a/lang/en/templates/locations/subnets.json b/lang/en/templates/locations/subnets.json deleted file mode 100644 index 65da254b..00000000 --- a/lang/en/templates/locations/subnets.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_endAddress": "End", - "lang_listOfSubnets": "List of subnets", - "lang_location": "Location", - "lang_startAddress": "Start", - "lang_thisListByLocation": "List by location" -} \ No newline at end of file diff --git a/lang/en/templates/main-menu.json b/lang/en/templates/main-menu.json deleted file mode 100644 index d22f90d7..00000000 --- a/lang/en/templates/main-menu.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "lang_backup": "Backup\/Restore", - "lang_client": "Client", - "lang_clientLog": "Client Log", - "lang_clientStats": "Client statistics", - "lang_configurationBasic": "PXE\/Boot", - "lang_configurationVariables": "Configuration Variables", - "lang_dozmod": "Tutor module", - "lang_eventLog": "Server Log", - "lang_internetAccess": "Internet access", - "lang_language": "Language", - "lang_localization": "Localization", - "lang_locations": "Rooms\/Locations", - "lang_login": "Login", - "lang_logout": "Logout", - "lang_needsSetup": "Setup incomplete", - "lang_news": "vmChooser news", - "lang_server": "Server", - "lang_serverStatus": "Server status", - "lang_settings": "Settings", - "lang_status": "Status", - "lang_translations": "Translations", - "lang_vmLocation": "VM Location", - "lang_warning": "Warning", - "lang_webInterface": "Web interface" -} \ No newline at end of file diff --git a/lang/en/templates/messagebox-error.json b/lang/en/templates/messagebox-error.json deleted file mode 100644 index c44dc44f..00000000 --- a/lang/en/templates/messagebox-error.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - -] \ No newline at end of file diff --git a/lang/en/templates/messagebox-info.json b/lang/en/templates/messagebox-info.json deleted file mode 100644 index 2c63c085..00000000 --- a/lang/en/templates/messagebox-info.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/lang/en/templates/messagebox-success.json b/lang/en/templates/messagebox-success.json deleted file mode 100644 index 2c63c085..00000000 --- a/lang/en/templates/messagebox-success.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/lang/en/templates/messagebox-warning.json b/lang/en/templates/messagebox-warning.json deleted file mode 100644 index 2c63c085..00000000 --- a/lang/en/templates/messagebox-warning.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/lang/en/templates/minilinux/download.json b/lang/en/templates/minilinux/download.json deleted file mode 100644 index 2c63c085..00000000 --- a/lang/en/templates/minilinux/download.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/lang/en/templates/minilinux/filelist.json b/lang/en/templates/minilinux/filelist.json deleted file mode 100644 index 89fed42b..00000000 --- a/lang/en/templates/minilinux/filelist.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lang_actual": "Actual", - "lang_canUpdate1": "At least one component of", - "lang_canUpdate2": "can be updated. For a smooth operation, it is recommended to keep all components up to date.", - "lang_configurationPackageNotFound": "Configuration package not found!", - "lang_desiredVersion": "Desired version", - "lang_filesInVersion": "Files for version", - "lang_outdated": "Outdated", - "lang_redownload": "Download again", - "lang_systemUpdated": "The system is up to date.", - "lang_update": "Update" -} \ No newline at end of file diff --git a/lang/en/templates/page-adduser.json b/lang/en/templates/page-adduser.json deleted file mode 100644 index 42bae6dc..00000000 --- a/lang/en/templates/page-adduser.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "lang_confirmation": "Confirm Password", - "lang_createUser": "Create User", - "lang_fullName": "Full Name", - "lang_password": "Password", - "lang_telephone": "Telephone", - "lang_username": "Username" -} \ No newline at end of file diff --git a/lang/en/templates/page-login.json b/lang/en/templates/page-login.json deleted file mode 100644 index 4b192a7a..00000000 --- a/lang/en/templates/page-login.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "lang_enter": "Enter", - "lang_login": "Login", - "lang_password": "Password", - "lang_register": "Register", - "lang_rememberID": "Remember ID", - "lang_username": "Username" -} \ No newline at end of file diff --git a/lang/en/templates/page-main-guest.json b/lang/en/templates/page-main-guest.json deleted file mode 100644 index 6526f5bd..00000000 --- a/lang/en/templates/page-main-guest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_introGuest": "This is the administration interface of the local bwLehrpool intallation. Please authenticate yourself to adjust settings.", - "lang_login": "Login", - "lang_noExistingAccount": "No account has been created yet. Sign up to become the administrator.", - "lang_register": "Register", - "lang_welcome": "Welcome" -} \ No newline at end of file diff --git a/lang/en/templates/page-main.json b/lang/en/templates/page-main.json deleted file mode 100644 index 8031ac1c..00000000 --- a/lang/en/templates/page-main.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "lang_bootMenuWarning": "The boot menu is outdated or has not been generated.", - "lang_configure": "Configure", - "lang_intro": "This is the bwLehrpool configuration interface.", - "lang_minilinuxMissing": "Important files from the mini Linux installation are missing.", - "lang_numerOfImagesMarkedForDeletion": "Images marked for deletion", - "lang_systemConfiguration": "System Configuration", - "lang_systemConfigurationNotChosen": "A system configuration has not been chosen yet.", - "lang_vmLocationNotSet": "A location for the virtual machine is not set yet.", - "lang_welcome": "Welcome" -} \ No newline at end of file diff --git a/lang/en/templates/page-minilinux.json b/lang/en/templates/page-minilinux.json deleted file mode 100644 index 2f59fa57..00000000 --- a/lang/en/templates/page-minilinux.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_errorGetting": "Error while downloading list!", - "lang_listObtained": "Downloading list..." -} \ No newline at end of file diff --git a/lang/en/templates/page-news.json b/lang/en/templates/page-news.json deleted file mode 100644 index df63658c..00000000 --- a/lang/en/templates/page-news.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lang_content": "Content", - "lang_date": "Date", - "lang_delete": "Delete", - "lang_editNews": "Edit news", - "lang_latestUpdate": "Latest update", - "lang_newsIntro": "Here you have the possibility to edit the news displayed to the bwLehrpool clients.", - "lang_newsOld": "Old News", - "lang_save": "Save", - "lang_show": "Show", - "lang_title": "Title" -} \ No newline at end of file diff --git a/lang/en/templates/page-syslog.json b/lang/en/templates/page-syslog.json deleted file mode 100644 index 71f61693..00000000 --- a/lang/en/templates/page-syslog.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "lang_client": "Client", - "lang_clientLog": "Client Log", - "lang_details": "Details", - "lang_event": "Event", - "lang_filter": "Filter", - "lang_go": "Go", - "lang_not": "not", - "lang_when": "When" -} \ No newline at end of file diff --git a/lang/en/templates/page-vmstore.json b/lang/en/templates/page-vmstore.json deleted file mode 100644 index 23ddbbd3..00000000 --- a/lang/en/templates/page-vmstore.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "lang_close": "Close", - "lang_intern": "Intern", - "lang_nfsHelp1": "An NFSv4\/3-Share is required. It should be readable by all the workstations, and writable for the satellite server. An example, assuming the satellite server has IP address 1.2.3.4:", - "lang_nfsHelp2": "Alternate configuration using all_squash. The exported directory should be owned (and be writable) by the user with uid 1234.", - "lang_noAdditionalInformation": "No additional cofiguration required", - "lang_password": "Password", - "lang_readOnly": "Read-only Access", - "lang_readWrite": "Read\/Write Access", - "lang_save": "Save", - "lang_username": "Username", - "lang_vmLocation": "VM Location", - "lang_vmLocationChoose": "Please choose where the images of virtual machines will be stored.", - "lang_vmLocationHelp1": "For test purposes, the VMs can be stored directly on the Satellite server. However, if you operate the delivered satellite vmdk please remember that you have only about 100GB of memory.", - "lang_vmLocationHelp2": "In productive operation, it makes sense for this to use a high-performance network storage. This network storage can be integrated via NFS or CIFS \/ SMB. In any case, it must be ensured that the satellite server has write access to this network storage to add a new Virtual Machine . When using NFSv3 this can be set up IP-based, for the use of CIFS \/ SMB, you can access data disclosures that would entitle them to write.", - "lang_vmLocationHelp3": "The bwLehrpool clients only need read access to the network storage (and for security reasons, really can only read). In CIFS \/ SMB You can do this most easily by allowing passwordless guest access with read access to the share." -} \ No newline at end of file diff --git a/lang/en/templates/pagenav.json b/lang/en/templates/pagenav.json deleted file mode 100644 index 2c63c085..00000000 --- a/lang/en/templates/pagenav.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/lang/en/templates/serversetup/ipaddress.json b/lang/en/templates/serversetup/ipaddress.json deleted file mode 100644 index 699aeacc..00000000 --- a/lang/en/templates/serversetup/ipaddress.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_active": "Active", - "lang_bootAddress": "Boot Address of the Server", - "lang_bootHint": "The Boot menu must be recreated after changing the IP address. Usually this is done automatically, but the process can also be triggered manually in the section of the boot menu.", - "lang_chooseIP": "Please select the IP address that the client server will use to boot.", - "lang_set": "Set" -} \ No newline at end of file diff --git a/lang/en/templates/serversetup/ipxe.json b/lang/en/templates/serversetup/ipxe.json deleted file mode 100644 index 39bb0d54..00000000 --- a/lang/en/templates/serversetup/ipxe.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "lang_bootBehavior": "Default Boot Behavior", - "lang_bootInfo": "Here adjustments can be made to the appearance of the boot menu.", - "lang_bootMenu": "Boot Menu", - "lang_bootMenuCreate": "Create Boot Menu", - "lang_close": "Close", - "lang_customEntry": "Custom entry", - "lang_example": "Example", - "lang_localHDD": "Local HDD", - "lang_masterPassword": "Master password", - "lang_masterPasswordHelp": "The master password is required to edit a boot menu entry. This should be set for security reasons.", - "lang_menuCustom": "Custom Extra Menu", - "lang_menuCustomHint1": "Here you have the opportunity to add your own menu code to the displayed PXE menu, eg to refer to other PXE server. The format corresponds to the syslinux menu format.", - "lang_menuCustomHint2": "You can create one or more entries. If you want to create an entry that starts automatically when the user makes a selection, assign as", - "lang_menuCustomHint3": "and select as the default boot behavior custom as well.", - "lang_menuDisplayTime": "Menu Display Time", - "lang_seconds": "Seconds" -} \ No newline at end of file diff --git a/lang/en/templates/serversetup/ipxe_update.json b/lang/en/templates/serversetup/ipxe_update.json deleted file mode 100644 index b33b12dd..00000000 --- a/lang/en/templates/serversetup/ipxe_update.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_generationFailed": "Could not generate boot menu. The bwLehrpool-System might not work properly. If you can't fix the problem, please report the error message above to the bwLehrpool project.", - "lang_menuGeneration": "Generating boot menu..." -} \ No newline at end of file diff --git a/lang/en/templates/statistics/clientlist.json b/lang/en/templates/statistics/clientlist.json deleted file mode 100644 index ae692154..00000000 --- a/lang/en/templates/statistics/clientlist.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "lang_address": "Address", - "lang_clientList": "List of selected machines", - "lang_cpuModel": "CPU", - "lang_gbRam": "RAM", - "lang_kvmSupport": "64\u2009Bit guests", - "lang_lastSeen": "Last seen", - "lang_machine": "Machine", - "lang_machineIdle": "Machine is powered on and is not used", - "lang_machineOccupied": "Machine is powered on and in use", - "lang_machineOff": "Machine is powered down, or is not running bwLehrpool", - "lang_realCores": "Cores", - "lang_tmpGb": "HDD temp" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/cpumodels.json b/lang/en/templates/statistics/cpumodels.json deleted file mode 100644 index 864933dd..00000000 --- a/lang/en/templates/statistics/cpumodels.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lang_cpuCores": "CPU cores", - "lang_modelCount": "Count", - "lang_modelName": "Model name", - "lang_modelStats": "PC models" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/id44.json b/lang/en/templates/statistics/id44.json deleted file mode 100644 index 0d0081a8..00000000 --- a/lang/en/templates/statistics/id44.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_machineCount": "Count", - "lang_partitionSize": "Size", - "lang_tempPartStats": "Temporary partition" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/kvmstate.json b/lang/en/templates/statistics/kvmstate.json deleted file mode 100644 index b4846473..00000000 --- a/lang/en/templates/statistics/kvmstate.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_kvmState": "State", - "lang_kvmStats": "64\u2009Bit guest support", - "lang_machineCount": "Count" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/machine-hdds.json b/lang/en/templates/statistics/machine-hdds.json deleted file mode 100644 index 8ce6801d..00000000 --- a/lang/en/templates/statistics/machine-hdds.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "lang_hdds": "Hard disk drives", - "lang_hours": "hours", - "lang_modelNo": "Model", - "lang_partName": "Name", - "lang_partSize": "Size", - "lang_partType": "Type", - "lang_pendingSectors": "Sectors pending reallocation", - "lang_powerOnTime": "Power on time", - "lang_reallocatedSectors": "Bad sectors", - "lang_serialNo": "Serial no", - "lang_total": "Total" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/machine-main.json b/lang/en/templates/statistics/machine-main.json deleted file mode 100644 index 1addd437..00000000 --- a/lang/en/templates/statistics/machine-main.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "lang_64bitSupport": "64\u2009Bit guest support", - "lang_cores": "Cores", - "lang_cpuModel": "CPU model", - "lang_firstSeen": "First seen", - "lang_hardwareSummary": "Hardware", - "lang_hostname": "Hostname", - "lang_ip": "IP address", - "lang_lastBoot": "Last boot", - "lang_lastSeen": "Last activity", - "lang_macAddr": "MAC address", - "lang_machineIdle": "Powered on, unused", - "lang_machineOccupied": "Powered on, in use", - "lang_machineOccupiedBy": "In use by", - "lang_machineOff": "bwLehrpool not running", - "lang_machineSummary": "Summary", - "lang_maximumAbbrev": "max.", - "lang_model": "Model", - "lang_ram": "Memory", - "lang_ramSlots": "Memory slots", - "lang_sockets": "Sockets", - "lang_tempPart": "Temp. partition", - "lang_usageState": "State", - "lang_uuid": "UUID", - "lang_virtualCores": "Virtual cores" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/machine-notes.json b/lang/en/templates/statistics/machine-notes.json deleted file mode 100644 index 7a13f28a..00000000 --- a/lang/en/templates/statistics/machine-notes.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_notes": "Notes", - "lang_save": "Save" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/machine-usage.json b/lang/en/templates/statistics/machine-usage.json deleted file mode 100644 index 398996f6..00000000 --- a/lang/en/templates/statistics/machine-usage.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_timebarDesc": "Visual representation of the last few days. Red parts mark periods where the client was occupied, green parts where the client was idle. Dimmed parts mark nights (10pm to 8am).", - "lang_usageDetails": "Detailed usage" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/memory.json b/lang/en/templates/statistics/memory.json deleted file mode 100644 index decdd021..00000000 --- a/lang/en/templates/statistics/memory.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_machineCount": "Count", - "lang_memoryStats": "Memory", - "lang_ramSize": "Size" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/newclients.json b/lang/en/templates/statistics/newclients.json deleted file mode 100644 index f7e55f3f..00000000 --- a/lang/en/templates/statistics/newclients.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_machine": "Client", - "lang_newMachines": "New machines" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/summary.json b/lang/en/templates/statistics/summary.json deleted file mode 100644 index b57c290f..00000000 --- a/lang/en/templates/statistics/summary.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lang_inUseMachines": "In use", - "lang_knownMachines": "Known clients", - "lang_onlineMachines": "Online clients", - "lang_withBadSectors": "Clients with potentially bad HDDs (more than 10 reallocated sectors)" -} \ No newline at end of file diff --git a/lang/en/templates/statistics/syslog.json b/lang/en/templates/statistics/syslog.json deleted file mode 100644 index 6737ca68..00000000 --- a/lang/en/templates/statistics/syslog.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_details": "Details", - "lang_event": "Event", - "lang_logHeadline": "Logging", - "lang_more": "More", - "lang_when": "When" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/_page.json b/lang/en/templates/sysconfig/_page.json deleted file mode 100644 index 6f139359..00000000 --- a/lang/en/templates/sysconfig/_page.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "lang_activate": "Activate", - "lang_active": "Active", - "lang_availableModules": "Available Configuration Modules", - "lang_availableSystem": "Available System Configuration", - "lang_close": "Close", - "lang_configurationModuleNotFound": "Configuration module not found!", - "lang_delete": "Delete", - "lang_deleteLong": "Delete module or configuration.", - "lang_download": "Download", - "lang_downloadLong": "Download module \"as is\".", - "lang_edit": "Edit", - "lang_editLong": "Edit module or configuration.", - "lang_helpModuleConfiguration": "Configuration modules are the building blocks from which a system configuration is created. Here you can create both generic modules by a wizard, as well as create completely custom modules (advanced Linux knowledge required).", - "lang_helpSystemConfiguration": "The fundamental localization of the bwLehrpool system is done through a system configuration. These include aspects such as the authentication method for users (eg Active Directory, LDAP), printer configuration, home directories, etc. A system configuration is composed of one or more configuration modules, which can be managed in the panel next to this one.", - "lang_legend": "Legend", - "lang_moduleConfiguration": "Module Configuration", - "lang_newConfiguration": "New Configuration", - "lang_newModule": "New Module", - "lang_rebuild": "Rebuild", - "lang_rebuildLong": "Rebuild module or configuration.", - "lang_rebuildOutdatedLong": "Rebuild module or configuration. The module\/configuration is outdated or missing and should be regenerated.", - "lang_show": "Show", - "lang_showLong": "Show content of module.", - "lang_systemConfiguration": "System Configuration", - "lang_systemConfigurationAlert": "Before you can create a system configuration, you must first create a configuration module.", - "lang_systemConfigurationNotFound": "No system configurations found. Create a new configuration from the configuration modules listed below." -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ad-finish.json b/lang/en/templates/sysconfig/ad-finish.json deleted file mode 100644 index 8f89046e..00000000 --- a/lang/en/templates/sysconfig/ad-finish.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_adStarted": "The AD-proxy is now configured and started ...", - "lang_generateModule": "Generate Module", - "lang_restartWizard": "Restart Wizard", - "lang_systemConfiguration": "System Configuration", - "lang_to": "To" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ad-selfsearch.json b/lang/en/templates/sysconfig/ad-selfsearch.json deleted file mode 100644 index 70db0620..00000000 --- a/lang/en/templates/sysconfig/ad-selfsearch.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "lang_back": "Back", - "lang_continueAnyway": "Continue anyway", - "lang_dnLookup": "Looking up bind dn", - "lang_homeAttributeExplanation": "Please select the attribute which holds the user's home directory.", - "lang_next": "Next", - "lang_onProblemSearchBase": "On failure, try to pass the bind dn and search base manually", - "lang_selectHomeAttribute": "Home attribute", - "lang_skip": "Skip" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ad-start.json b/lang/en/templates/sysconfig/ad-start.json deleted file mode 100644 index ff35fc03..00000000 --- a/lang/en/templates/sysconfig/ad-start.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "lang_adText1": "To set up user authentication through Active Directory, a dedicated user is required in AD next to the address of the server, which is addressed by the AD.", - "lang_adText2": "This user does not need special rights, you can follow this user to evade security and the rights to log on. The user only needs to have sufficient permissions to perform an LDAP Bind on AD, and search for users.", - "lang_adText3": "Next the distinguished name of the user must be specified. You can determine this by dsquery command line program on a domain controller as the following call:", - "lang_adText4": "After entering all required data in the next step, it checks whether communication is possible with the AD.", - "lang_asteriskMandatory": "Fields marked with (*) are mandatory", - "lang_bindDN": "Bind DN", - "lang_close": "Close", - "lang_customCertificate": "Additional (intermediate) certificates required for certificate validation", - "lang_helpHomeAttrHead": "Name of the home directory attribute", - "lang_helpHomeAttrText": "Here you can specify the name of the attribute on the Active Directory that contains the path of the home directory server. Usually this is \"homeDirectory\". If you leave this blank, the wiszard will try to determine the attribute name automatically. If home directories don't work, check the client log (Status->Client log) and the LDAP proxy log (Status->Server status).", - "lang_homeAttr": "Home attribute", - "lang_moduleTitle": "Title", - "lang_next": "Next", - "lang_password": "Password", - "lang_searchBase": "Search Base", - "lang_ssl": "SSL", - "lang_sslDescription": "Use SSL encryption to talk to AD server.", - "lang_userDirectory": "User Directory", - "lang_userDirectoryInfo1": "Optional: If the clients should embed a separate directory (home directory, user directory) from a server for the user, please enter here the format in UNC notation, eg", - "lang_userDirectoryInfo2": "%s is a placeholder for the user's login name.", - "lang_userDirectoryInfo3": "The directory is loaded with the same credentials that the user specifies when login. (That is no Kerberos support, etc.)" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ad_ldap-checkconnection.json b/lang/en/templates/sysconfig/ad_ldap-checkconnection.json deleted file mode 100644 index 6a924f8b..00000000 --- a/lang/en/templates/sysconfig/ad_ldap-checkconnection.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "lang_back": "Back", - "lang_connectionWait": "Checking connection...", - "lang_next": "Next", - "lang_noOpenPort": "There is no open LDAP port on this server.", - "lang_noValidCert": "The server did not supply a certificate, or the certificate is invalid.", - "lang_selfSignedNote": "The certificate of this server cannot be verified using the builtin trust store. If you know that the server's certificate was signed by an unknown CA, you can try to proceed. The chain will then be extracted from the server, which should be successful in most cases. If the authentication module does not work afterwards, check the LDAP-proxy logs on the server status page." -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ad_ldap-checkcredentials.json b/lang/en/templates/sysconfig/ad_ldap-checkcredentials.json deleted file mode 100644 index 2b83a231..00000000 --- a/lang/en/templates/sysconfig/ad_ldap-checkcredentials.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lang_back": "Back", - "lang_connectionWait": "The connection to the specified AD server is now checked. Please wait a moment.", - "lang_onProblemSearchBase": "If this step fails and you didn't supply a search base, try again with a valid one.", - "lang_skip": "Skip" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ad_ldap-homedir.json b/lang/en/templates/sysconfig/ad_ldap-homedir.json deleted file mode 100644 index 82550b8a..00000000 --- a/lang/en/templates/sysconfig/ad_ldap-homedir.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "lang_folderRedirection": "Folder Redirection", - "lang_handlingNotes": "Here you can configure how network shares (like the user's home directory) are mapped inside the VM. Old Versions of bwLehrpool used the VMware Shared Folder technique, which could cause problems with certain file servers. The new \"native mode\" works much better, but on Windows guests, it requires that you (1) use an smb\/cifs file server (Windows Server, Linux with Samba) and (2) have openslx.exe setup to autorun in the VM (this is already configured for bwLehrpool templates). Native mode with fallback is experimental and known to cause temporary freezes with some VMs. Use with care. IMPORTANT: Pick a drive letter for the home directory that will be free in the Virtual Machines. Otherwise, a random letter will be assigned.", - "lang_homedirHandling": "(Home) directory handling", - "lang_mapModeNative": "Natively map inside the VM [openslx.exe]", - "lang_mapModeNativeFallback": "Natively map inside VM; fallback to VMware Shared Folders", - "lang_mapModeNone": "Don't map shares at all", - "lang_mapModeVmware": "VMware Shared Folders [VMwareTools]", - "lang_next": "Next", - "lang_redirectionWarning": "WARNING: This feature is experimental. It remaps the selected folders after the VM booted (via openslx.exe) to the logged in user's home drive. This might cause problems with applications that start before the pathes are patched, as they will see the old unpatched settings. Please note that this is usign undocumented or unsupported techniques to achieve this goal. It is not guaranteed that this method will work in future versions or updates of Windows. If you want to reliably remap these directories, you might want to change their locations in the VM before uploading it.", - "lang_shareDesktop": "Desktop (Might hide shortcuts created by the tutor)", - "lang_shareDocuments": "My Documents", - "lang_shareDownloads": "Downloads", - "lang_shareHomeDrive": "Home drive letter (Windows)", - "lang_shareMapCreate": "Create folders on network share if they don't exist", - "lang_shareMedia": "My Music, Videos, Pictures", - "lang_shareOther": "Other (Saved Games, Contacts, Favorites, ...)", - "lang_shareRemapMode": "Mapping mode" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/branding-check.json b/lang/en/templates/sysconfig/branding-check.json deleted file mode 100644 index 6a481d8b..00000000 --- a/lang/en/templates/sysconfig/branding-check.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_brandingInfo": "Below you can check the selected logo. If you can not see the logo, please check whether you have used a valid SVG image. Alternatively, it is possible that during processing of the image, an error occurred. Therefore, you can save the module anyway and test whether the logo is displayed in the bwLehrpool system.", - "lang_save": "Save", - "lang_title": "Title" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/branding-start.json b/lang/en/templates/sysconfig/branding-start.json deleted file mode 100644 index 4423784d..00000000 --- a/lang/en/templates/sysconfig/branding-start.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "lang_branding": "For best results, you should upload the logo in SVG format. SVG is a vector graphics format, which is advantageous for scaling. A good source for SVG logos of universities and colleges is their respective Wikipedia article.", - "lang_browseForFile": "Browse", - "lang_computerLoad": "Load image from local computer", - "lang_or": "or", - "lang_selectFile": "Please select a file", - "lang_upload": "Upload", - "lang_urlLoad": "Load image from URL" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/cfg-finish.json b/lang/en/templates/sysconfig/cfg-finish.json deleted file mode 100644 index b8729636..00000000 --- a/lang/en/templates/sysconfig/cfg-finish.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_configurationActive": "Enable configuration", - "lang_configurationSuccess": "The configuration has been successfully created." -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/cfg-start.json b/lang/en/templates/sysconfig/cfg-start.json deleted file mode 100644 index a00a6720..00000000 --- a/lang/en/templates/sysconfig/cfg-start.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_configuration": "Configuration", - "lang_configurationChoose": "Please select which modules will be used for this configuration.", - "lang_name": "Name", - "lang_next": "Next", - "lang_noModuleOfType": "No module of this type found." -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/config-module-list.json b/lang/en/templates/sysconfig/config-module-list.json deleted file mode 100644 index ff30c0b4..00000000 --- a/lang/en/templates/sysconfig/config-module-list.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_noContent": "No content!", - "lang_show": "Show" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/custom-filelist.json b/lang/en/templates/sysconfig/custom-filelist.json deleted file mode 100644 index 50bec5b5..00000000 --- a/lang/en/templates/sysconfig/custom-filelist.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "lang_back": "Back" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/custom-fileselect.json b/lang/en/templates/sysconfig/custom-fileselect.json deleted file mode 100644 index 2ae25e16..00000000 --- a/lang/en/templates/sysconfig/custom-fileselect.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_checkFileContent": "Here you have the possibility to check the contents of the archive again.", - "lang_moduleName": "Module Name", - "lang_next": "Next" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/custom-upload.json b/lang/en/templates/sysconfig/custom-upload.json deleted file mode 100644 index 26b7c186..00000000 --- a/lang/en/templates/sysconfig/custom-upload.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "lang_browseForFile": "Browse", - "lang_customModuleInfo1": "About a custom module, it is possible to add arbitrary files to a Linux system that is booted clients. For this purpose, an archive can be uploaded using a file system structure that is extracted in this form 1:1 in the booted Linux.", - "lang_customModuleInfo2": "Example: If the uploaded archive is the file etc\/example.conf, this file will be located as \/etc\/example.conf to a booted client.", - "lang_selectFile": "Please select an archive", - "lang_supportedFiles": "Supported File Formats", - "lang_upload": "Upload" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ldap-checkconnection.json b/lang/en/templates/sysconfig/ldap-checkconnection.json deleted file mode 100644 index 52fbae9e..00000000 --- a/lang/en/templates/sysconfig/ldap-checkconnection.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_back": "Back", - "lang_connectionWait": "Checking connection, please wait", - "lang_next": "Next" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ldap-checkcredentials.json b/lang/en/templates/sysconfig/ldap-checkcredentials.json deleted file mode 100644 index 2a8723c9..00000000 --- a/lang/en/templates/sysconfig/ldap-checkcredentials.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lang_back": "Back", - "lang_connectionWait": "Checking LDAP credentials", - "lang_onProblemSearchBase": "If no users are found, please check the search base", - "lang_skip": "Next" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ldap-finish.json b/lang/en/templates/sysconfig/ldap-finish.json deleted file mode 100644 index bd15bafc..00000000 --- a/lang/en/templates/sysconfig/ldap-finish.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lang_generateModule": "Generating module", - "lang_ldapStarted": "The LDAP proxy has been launched", - "lang_restartWizard": "Restart wizard", - "lang_toSystemConfiguration": "Go to system configuration" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/ldap-start.json b/lang/en/templates/sysconfig/ldap-start.json deleted file mode 100644 index 45ba19f1..00000000 --- a/lang/en/templates/sysconfig/ldap-start.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "lang_bindDN": "Bind domain", - "lang_close": "Close", - "lang_customCertificate": "Additional (intermediate) certificates required for certificate validation", - "lang_ldapText1": "Here you can create a configuration module to authenticate agains an LDAP server", - "lang_ldapText2": "An LDAP-Proxy will be launched on this server. This means the LDAP-Server must be reachable from it. The client PCs in the labs however don't have to be able to talk to the LDAP server \u2013 they will use the proxy running on this server.", - "lang_moduleTitle": "Module name", - "lang_next": "Next", - "lang_password": "Password", - "lang_searchBase": "Search base", - "lang_ssl": "SSL", - "lang_sslDescription": "Use SSL to connect to the LDAP-Server. (The connection between clients and proxy uses SSL in either case.) Some LDAP servers require SSL for authenticating connections.", - "lang_userDirectory": "Home-Directory", - "lang_userDirectoryInfo1": "UNC-path to home directory of user. '%s' can be used as a placeholder for the account name.", - "lang_userDirectoryInfo2": "Currently, only CIFS\/SMB is supported." -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/sshconfig-start.json b/lang/en/templates/sysconfig/sshconfig-start.json deleted file mode 100644 index 1ce553cd..00000000 --- a/lang/en/templates/sysconfig/sshconfig-start.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "lang_allowPass": "Allow password login", - "lang_allowPassInfo": "When active, logins via username and password are allowed. Otherwise, only pubkey authentication is possible.", - "lang_listenPort": "Listen port", - "lang_listenPortInfo": "Listen port for the sshd. Default is 22.", - "lang_moduleName": "Module name", - "lang_rootKey": "root pubkey", - "lang_rootKeyInfo": "Here you can add the public key of a keypair that you want to use for authentication as root-user. Leave this field blank to disable the feature.", - "lang_save": "Save" -} \ No newline at end of file diff --git a/lang/en/templates/sysconfig/start.json b/lang/en/templates/sysconfig/start.json deleted file mode 100644 index 4567d649..00000000 --- a/lang/en/templates/sysconfig/start.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_add": "Add", - "lang_moduleChoose": "Please select which type of configuration module you want to create." -} \ No newline at end of file diff --git a/lang/en/templates/systemstatus/_page.json b/lang/en/templates/systemstatus/_page.json deleted file mode 100644 index f698521d..00000000 --- a/lang/en/templates/systemstatus/_page.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "lang_addressConfiguration": "Address Configuration", - "lang_advanced": "Advanced \/ Debug", - "lang_dmsdLog": "dmsd log", - "lang_iAmSure": "Yes, I am sure", - "lang_ldadpLog": "AD\/LDAP proxy log", - "lang_maintenance": "Maintenance", - "lang_services": "Services", - "lang_space": "Space", - "lang_system": "System" -} \ No newline at end of file diff --git a/lang/en/templates/systemstatus/addresses.json b/lang/en/templates/systemstatus/addresses.json deleted file mode 100644 index 2c63c085..00000000 --- a/lang/en/templates/systemstatus/addresses.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/lang/en/templates/systemstatus/diskstat.json b/lang/en/templates/systemstatus/diskstat.json deleted file mode 100644 index 6c880ebe..00000000 --- a/lang/en/templates/systemstatus/diskstat.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lang_capacity": "Capacity", - "lang_foundStore": "Found:", - "lang_free": "Free", - "lang_goToStoreConf": "Go to VM store configuration", - "lang_storeMissingExpected": "VM store not mounted. Expected:", - "lang_storeNotConfigured": "No VM store configured!", - "lang_systemPartition": "System Partition", - "lang_systemStoreError": "Error querying available system storage", - "lang_vmStore": "VM Store", - "lang_vmStoreError": "Error determining available space of the VM storage. Please check the configuration." -} \ No newline at end of file diff --git a/lang/en/templates/systemstatus/services.json b/lang/en/templates/systemstatus/services.json deleted file mode 100644 index 2c63c085..00000000 --- a/lang/en/templates/systemstatus/services.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/lang/en/templates/systemstatus/systeminfo.json b/lang/en/templates/systemstatus/systeminfo.json deleted file mode 100644 index 602693f5..00000000 --- a/lang/en/templates/systemstatus/systeminfo.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "lang_attention": "Attention!", - "lang_average": "Average", - "lang_cpuLoad": "CPU Load", - "lang_free": "Free", - "lang_logicCPUs": "Logic CPUs", - "lang_notDetermined": "Could not be determined", - "lang_occupied": "Occupied", - "lang_onlyOS": "OS Only", - "lang_ramUsage": "RAM Usage", - "lang_swapUsage": "swap Usage", - "lang_swapWarning": "Memory swap is being used. This may be an indication that the satellite server does not have enough physical memory available. In the case of performance problems or server instability you should consider equipping the server with more RAM.", - "lang_total": "Total", - "lang_uptimeOS": "OS Uptime" -} \ No newline at end of file diff --git a/lang/en/templates/translation/_page.json b/lang/en/templates/translation/_page.json deleted file mode 100644 index 5a48b696..00000000 --- a/lang/en/templates/translation/_page.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "lang_adminInfo": "In this section you can change the JSON tags that contains the translated texts used by the site. To do this, select a template below to modify their respective tags. Alternatively, click the link below to change the messages of the site.", - "lang_editConfigModule": "Edit config module strings", - "lang_editHardcoded": "Edit hardcoded strings", - "lang_editMessages": "Edit Messages", - "lang_editSettings": "Edit configuration variables related strings", - "lang_editTemplates": "Edit template strings", - "lang_langAdministration": "Language Administration" -} \ No newline at end of file diff --git a/lang/en/templates/translation/edit.json b/lang/en/templates/translation/edit.json deleted file mode 100644 index 05c6697a..00000000 --- a/lang/en/templates/translation/edit.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lang_back": "Back", - "lang_createTag": "Create TAG", - "lang_deleteTAG": "Delete", - "lang_englishTAG": "English TAG", - "lang_germanTAG": "German TAG", - "lang_newTAG": "New TAG", - "lang_portugueseTAG": "Portuguese TAG", - "lang_save": "Save", - "lang_templateAdminHelp": "Here you can translate and edit phrases and texts.", - "lang_templateHint": "Hint: Yellow lines indicate a translation is missing and red lines indicate a tag is not being used by the template." -} \ No newline at end of file diff --git a/lang/en/templates/translation/template-list.json b/lang/en/templates/translation/template-list.json deleted file mode 100644 index e3feb70b..00000000 --- a/lang/en/templates/translation/template-list.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_adminInfo": "This is a list of all templates. The \u0022status\u0022-column tells if there are translations missing, or unused tags are defined.", - "lang_langAdministration": "Templates", - "lang_status": "Status" -} \ No newline at end of file diff --git a/lang/en/templates/vmstore/mount.json b/lang/en/templates/vmstore/mount.json deleted file mode 100644 index 29814430..00000000 --- a/lang/en/templates/vmstore/mount.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "lang_back": "Back", - "lang_configure": "Configure", - "lang_vmLocationConfiguration": "VM location is configured" -} \ No newline at end of file diff --git a/lang/en/templates/webinterface/httpd-restart.json b/lang/en/templates/webinterface/httpd-restart.json deleted file mode 100644 index 0a7d4aea..00000000 --- a/lang/en/templates/webinterface/httpd-restart.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lang_applyingSettings": "Applying settings", - "lang_installAndRestart": "Installing certificate and restarting web server" -} \ No newline at end of file diff --git a/lang/en/templates/webinterface/https.json b/lang/en/templates/webinterface/https.json deleted file mode 100644 index 64631a9a..00000000 --- a/lang/en/templates/webinterface/https.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "lang_HttpsIsDisabled": "HTTPS is currently disabled", - "lang_caChain": "Here you can paste an optional certificate chain. It should only be required if you have a certificate that was not directly signed by a certificate authority known by the browsers. It should contain one or more certificate blocks, looking just like the certificate above.", - "lang_certificate": "Please paste your certificate below. It has to be in base64 encoded x509 format (sometimes called pem). It should look something like this:", - "lang_customCert": "Supply own certificate", - "lang_description": "Here you can set whether the web interface should be accessible via https. You can chose if you want to use a random self signed certificate, or supply your own.", - "lang_httpsSettings": "HTTPS settings", - "lang_noHttps": "Disable HTTPS, delete current certificate", - "lang_privateKey": "Please paste the private key belonging to the certificate here. It has to be in \"pem\" format too, which should look like this:", - "lang_randomCert": "Genenrate new self-signed certificate", - "lang_save": "Save" -} \ No newline at end of file diff --git a/lang/en/templates/webinterface/passwords.json b/lang/en/templates/webinterface/passwords.json deleted file mode 100644 index 2db88ae2..00000000 --- a/lang/en/templates/webinterface/passwords.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "lang_description": "Set whether password fields should be masked or not. The password field of the login page to the web interface is always masked.", - "lang_hidePasswords": "Mask passwords", - "lang_passwordFields": "Password fields", - "lang_save": "Save", - "lang_showPasswords": "Show passwords" -} \ No newline at end of file diff --git a/lang/pt/templates/sysconfig/ad_ldap-homedir.json b/lang/pt/templates/sysconfig/ad_ldap-homedir.json deleted file mode 100644 index c44dc44f..00000000 --- a/lang/pt/templates/sysconfig/ad_ldap-homedir.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - -] \ No newline at end of file diff --git a/modules/adduser.inc.php b/modules/adduser.inc.php deleted file mode 100644 index c236cb6f..00000000 --- a/modules/adduser.inc.php +++ /dev/null @@ -1,60 +0,0 @@ - $_POST['user'], - 'pass' => Crypto::hash6($_POST['pass1']), - 'fullname' => $_POST['fullname'], - 'phone' => $_POST['phone'], - 'email' => $_POST['email'], - ); - if (Database::exec('INSERT INTO user SET login = :user, passwd = :pass, fullname = :fullname, phone = :phone, email = :email', $data) != 1) { - Util::traceError('Could not create new user in DB'); - } - // Make it superadmin if first user. This method sucks as it's a race condition but hey... - $ret = Database::queryFirst('SELECT Count(*) AS num FROM user'); - if ($ret !== false && $ret['num'] == 1) { - Database::exec('UPDATE user SET permissions = 1'); - EventLog::clear(); - EventLog::info('Created first user ' . $_POST['user']); - } else { - EventLog::info(User::getName() . ' created user ' . $_POST['user']); - } - Message::addInfo('adduser-success'); - Util::redirect('?do=Session&action=login'); - } - } - } - - protected function doRender() - { - // No user was added, check if current user is allowed to add a new user - // Currently you can only add users if there is no user yet. :) - if (!User::hasPermission('superadmin') && Database::queryFirst('SELECT userid FROM user LIMIT 1') !== false) { - Message::addError('adduser-disabled'); - } else { - - Render::setTitle(Dictionary::translate('lang_createUser')); - Render::addTemplate('page-adduser', $_POST); - } - } - -} diff --git a/modules/adduser/config.json b/modules/adduser/config.json new file mode 100644 index 00000000..d5da4cc8 --- /dev/null +++ b/modules/adduser/config.json @@ -0,0 +1,4 @@ +{ + "category":"hidden", + "enabled":"true" +} diff --git a/modules/adduser/module.inc.php b/modules/adduser/module.inc.php new file mode 100644 index 00000000..c236cb6f --- /dev/null +++ b/modules/adduser/module.inc.php @@ -0,0 +1,60 @@ + $_POST['user'], + 'pass' => Crypto::hash6($_POST['pass1']), + 'fullname' => $_POST['fullname'], + 'phone' => $_POST['phone'], + 'email' => $_POST['email'], + ); + if (Database::exec('INSERT INTO user SET login = :user, passwd = :pass, fullname = :fullname, phone = :phone, email = :email', $data) != 1) { + Util::traceError('Could not create new user in DB'); + } + // Make it superadmin if first user. This method sucks as it's a race condition but hey... + $ret = Database::queryFirst('SELECT Count(*) AS num FROM user'); + if ($ret !== false && $ret['num'] == 1) { + Database::exec('UPDATE user SET permissions = 1'); + EventLog::clear(); + EventLog::info('Created first user ' . $_POST['user']); + } else { + EventLog::info(User::getName() . ' created user ' . $_POST['user']); + } + Message::addInfo('adduser-success'); + Util::redirect('?do=Session&action=login'); + } + } + } + + protected function doRender() + { + // No user was added, check if current user is allowed to add a new user + // Currently you can only add users if there is no user yet. :) + if (!User::hasPermission('superadmin') && Database::queryFirst('SELECT userid FROM user LIMIT 1') !== false) { + Message::addError('adduser-disabled'); + } else { + + Render::setTitle(Dictionary::translate('lang_createUser')); + Render::addTemplate('page-adduser', $_POST); + } + } + +} diff --git a/modules/adduser/templates/page-adduser.html b/modules/adduser/templates/page-adduser.html new file mode 100644 index 00000000..0b097890 --- /dev/null +++ b/modules/adduser/templates/page-adduser.html @@ -0,0 +1,28 @@ +
+ + + +
+
{{lang_username}} *
+
+
+
+
{{lang_password}} *
+
+
+
+
+
{{lang_fullName}} *
+
+
+
+
{{lang_telephone}}
+
+
+
+
E-Mail
+
+
+ + +
\ No newline at end of file diff --git a/modules/backup.inc.php b/modules/backup.inc.php deleted file mode 100644 index 24352a9a..00000000 --- a/modules/backup.inc.php +++ /dev/null @@ -1,134 +0,0 @@ -action = Request::post('action'); - if ($this->action === 'backup') { - $this->backup(); - } elseif ($this->action === 'restore') { - $this->restore(); - } - } - - protected function doRender() - { - Render::setTitle(Dictionary::translate('lang_titleBackup')); - if ($this->action === 'restore') { - Render::addTemplate('backup/restore', $this->templateData); - } else { - Render::addScriptBottom('fileselect'); - Render::addTemplate('backup/_page'); - } - } - - private function backup() - { - $task = Taskmanager::submit('BackupRestore', array('mode' => 'backup')); - if (!isset($task['id'])) { - Message::addError('backup-failed'); - Util::redirect('?do=Backup'); - } - $task = Taskmanager::waitComplete($task, 30000); - if (!Taskmanager::isFinished($task) || !isset($task['data']['backupFile'])) { - Taskmanager::addErrorMessage($task); - Util::redirect('?do=Backup'); - } - while ((@ob_get_level()) > 0) - @ob_end_clean(); - $fh = @fopen($task['data']['backupFile'], 'rb'); - if ($fh === false) { - Message::addError('error-read', $task['data']['backupFile']); - Util::redirect('?do=Backup'); - } - Header('Content-Type: application/octet-stream', true); - Header('Content-Disposition: attachment; filename=' . 'satellite-backup_v' . Database::getExpectedSchemaVersion() . '_' . date('Y.m.d-H.i.s') . '.tgz'); - Header('Content-Length: ' . @filesize($task['data']['backupFile'])); - while (!feof($fh)) { - $data = fread($fh, 16000); - if ($data === false) { - EventLog::failure('Could not stream system backup to browser - backup corrupted!'); - die("\r\n\nDOWNLOAD INTERRUPTED!\n"); - } - echo $data; - @ob_flush(); - @flush(); - } - @fclose($fh); - @unlink($task['data']['backupFile']); - die(); - } - - private function restore() - { - if (!isset($_FILES['backupfile'])) { - Message::addError('missing-file'); - Util::redirect('?do=Backup'); - } - if ($_FILES['backupfile']['error'] != UPLOAD_ERR_OK) { - Message::addError('upload-failed', Util::uploadErrorString($_FILES['backupfile']['error'])); - Util::redirect('?do=Backup'); - } - $tempfile = '/tmp/bwlp-' . mt_rand(1, 100000) . '-' . crc32($_SERVER['REMOTE_ADDR']) . '.tgz'; - if (!move_uploaded_file($_FILES['backupfile']['tmp_name'], $tempfile)) { - Message::addError('error-write', $tempfile); - Util::redirect('?do=Backup'); - } - // Got uploaded file, now shut down all the daemons etc. - $parent = Trigger::stopDaemons(null, $this->templateData); - // Unmount store - $task = Taskmanager::submit('MountVmStore', array( - 'address' => 'null', - 'type' => 'images', - 'parentTask' => $parent, - 'failOnParentFail' => false - )); - if (isset($task['id'])) { - $this->templateData['mountid'] = $task['id']; - $parent = $task['id']; - } - EventLog::info('Creating backup, v' . Database::getExpectedSchemaVersion() . ' on ' . Property::getServerIp()); - // Finally run restore - $task = Taskmanager::submit('BackupRestore', array( - 'mode' => 'restore', - 'backupFile' => $tempfile, - 'parentTask' => $parent, - 'failOnParentFail' => false, - 'restoreOpenslx' => Request::post('restore_openslx', 'off') === 'on', - 'restoreDozmod' => Request::post('restore_dozmod', 'off') === 'on', - )); - if (isset($task['id'])) { - $this->templateData['restoreid'] = $task['id']; - $parent = $task['id']; - TaskmanagerCallback::addCallback($task, 'dbRestored'); - } - // Wait a bit - $task = Taskmanager::submit('SleepTask', array( - 'seconds' => 3, - 'parentTask' => $parent, - 'failOnParentFail' => false - )); - if (isset($task['id'])) - $parent = $task['id']; - // Reboot - $task = Taskmanager::submit('Reboot', array( - 'parentTask' => $parent, - 'failOnParentFail' => false - )); - // Leave this comment so the i18n scanner finds it: - // Message::addSuccess('restore-done'); - if (isset($task['id'])) - $this->templateData['rebootid'] = $task['id']; - } - -} diff --git a/modules/backup/config.json b/modules/backup/config.json new file mode 100644 index 00000000..4e7fa5fb --- /dev/null +++ b/modules/backup/config.json @@ -0,0 +1,4 @@ +{ + "category":"content", + "enabled":"true" +} diff --git a/modules/backup/module.inc.php b/modules/backup/module.inc.php new file mode 100644 index 00000000..4095f875 --- /dev/null +++ b/modules/backup/module.inc.php @@ -0,0 +1,164 @@ +action = Request::post('action'); + if ($this->action === 'backup') { + $this->backup(); + } elseif ($this->action === 'restore') { + $this->restore(); + } + } + + protected function doRender() + { + Render::setTitle(Dictionary::translate('lang_titleBackup')); + if ($this->action === 'restore') { + Render::addTemplate('restore', $this->templateData); + } else { + Render::addScriptBottom('fileselect'); + Render::addTemplate('_page'); + } + } + + private function backup() + { + $task = Taskmanager::submit('BackupRestore', array('mode' => 'backup')); + if (!isset($task['id'])) { + Message::addError('backup-failed'); + Util::redirect('?do=Backup'); + } + $task = Taskmanager::waitComplete($task, 30000); + if (!Taskmanager::isFinished($task) || !isset($task['data']['backupFile'])) { + Taskmanager::addErrorMessage($task); + Util::redirect('?do=Backup'); + } + while ((@ob_get_level()) > 0) + @ob_end_clean(); + $fh = @fopen($task['data']['backupFile'], 'rb'); + if ($fh === false) { + Message::addError('error-read', $task['data']['backupFile']); + Util::redirect('?do=Backup'); + } + Header('Content-Type: application/octet-stream', true); + Header('Content-Disposition: attachment; filename=' . 'satellite-backup_v' . Database::getExpectedSchemaVersion() . '_' . date('Y.m.d-H.i.s') . '.tgz'); + Header('Content-Length: ' . @filesize($task['data']['backupFile'])); + while (!feof($fh)) { + $data = fread($fh, 16000); + if ($data === false) { + EventLog::failure('Could not stream system backup to browser - backup corrupted!'); + die("\r\n\nDOWNLOAD INTERRUPTED!\n"); + } + echo $data; + @ob_flush(); + @flush(); + } + @fclose($fh); + @unlink($task['data']['backupFile']); + die(); + } + + private function restore() + { + if (!isset($_FILES['backupfile'])) { + Message::addError('missing-file'); + Util::redirect('?do=Backup'); + } + if ($_FILES['backupfile']['error'] != UPLOAD_ERR_OK) { + Message::addError('upload-failed', Util::uploadErrorString($_FILES['backupfile']['error'])); + Util::redirect('?do=Backup'); + } + $tempfile = '/tmp/bwlp-' . mt_rand(1, 100000) . '-' . crc32($_SERVER['REMOTE_ADDR']) . '.tgz'; + if (!move_uploaded_file($_FILES['backupfile']['tmp_name'], $tempfile)) { + Message::addError('error-write', $tempfile); + Util::redirect('?do=Backup'); + } + // Got uploaded file, now shut down all the daemons etc. + $parent = Trigger::stopDaemons(null, $this->templateData); + // Unmount store + $task = Taskmanager::submit('MountVmStore', array( + 'address' => 'null', + 'type' => 'images', + 'parentTask' => $parent, + 'failOnParentFail' => false + )); + if (isset($task['id'])) { + $this->templateData['mountid'] = $task['id']; + $parent = $task['id']; + } + EventLog::info('Creating backup, v' . Database::getExpectedSchemaVersion() . ' on ' . Property::getServerIp()); + // Finally run restore + $task = Taskmanager::submit('BackupRestore', array( + 'mode' => 'restore', + 'backupFile' => $tempfile, + 'parentTask' => $parent, + 'failOnParentFail' => false, + 'restoreOpenslx' => Request::post('restore_openslx', 'off') === 'on', + 'restoreDozmod' => Request::post('restore_dozmod', 'off') === 'on', + )); + if (isset($task['id'])) { + $this->templateData['restoreid'] = $task['id']; + $parent = $task['id']; + TaskmanagerCallback::addCallback($task, 'dbRestored'); + } + // Wait a bit + $task = Taskmanager::submit('SleepTask', array( + 'seconds' => 3, + 'parentTask' => $parent, + 'failOnParentFail' => false + )); + if (isset($task['id'])) + $parent = $task['id']; + // Reboot + $task = Taskmanager::submit('Reboot', array( + 'parentTask' => $parent, + 'failOnParentFail' => false + )); + // Leave this comment so the i18n scanner finds it: + // Message::addSuccess('restore-done'); + if (isset($task['id'])) + $this->templateData['rebootid'] = $task['id']; + } + private function stopDaemons($parent) + { + $task = Taskmanager::submit('SyncdaemonLauncher', array( + 'operation' => 'stop', + 'parentTask' => $parent, + 'failOnParentFail' => false + )); + if (isset($task['id'])) { + $this->templateData['syncid'] = $task['id']; + $parent = $task['id']; + } + $task = Taskmanager::submit('DozmodLauncher', array( + 'operation' => 'stop', + 'parentTask' => $parent, + 'failOnParentFail' => false + )); + if (isset($task['id'])) { + $this->templateData['dmsdid'] = $task['id']; + $parent = $task['id']; + } + $task = Taskmanager::submit('LdadpLauncher', array( + 'ids' => array(), + 'parentTask' => $parent, + 'failOnParentFail' => false + )); + if (isset($task['id'])) { + $this->templateData['ldadpid'] = $task['id']; + $parent = $task['id']; + } + return $parent; + } +} diff --git a/modules/backup/templates/_page.html b/modules/backup/templates/_page.html new file mode 100644 index 00000000..47b5a174 --- /dev/null +++ b/modules/backup/templates/_page.html @@ -0,0 +1,41 @@ +

{{lang_backupRestore}}

+ +
+ + +
+
{{lang_backup}}
+
+

{{lang_backupDescription}}

+ +
+
+
+ +
+ + +
+
{{lang_restore}}
+
+

{{lang_restoreDescription}}

+
+ + + + {{lang_browseForFile}}… + + +
+
+ +

{{lang_systemExplanation}}

+
+
+ +

{{lang_dozmodExplanation}}

+
+ +
+
+
\ No newline at end of file diff --git a/modules/backup/templates/restore.html b/modules/backup/templates/restore.html new file mode 100644 index 00000000..4494a993 --- /dev/null +++ b/modules/backup/templates/restore.html @@ -0,0 +1,62 @@ +
+
{{lang_backup}}
+
+
+
{{lang_stopping}} syncdaemon
+
{{lang_stopping}} dmsd
+
{{lang_stopping}} ldadp
+
{{lang_stopping}} vmstore
+
{{lang_restoreConfig}}
+
{{lang_reboot}}
+
+ + +
+
+ + diff --git a/modules/baseconfig.inc.php b/modules/baseconfig.inc.php deleted file mode 100644 index 152e3372..00000000 --- a/modules/baseconfig.inc.php +++ /dev/null @@ -1,127 +0,0 @@ -qry_extra[] = array( - 'name' => 'distroid', - 'value' => (int)$_REQUEST['distroid'], - 'table' => 'setting_distro', - ); - if (isset($_REQUEST['poolid'])) { - $this->qry_extra[] = array( - 'name' => 'poolid', - 'value' => (int)$_REQUEST['poolid'], - 'table' => 'setting_pool', - ); - } - } - - if (isset($_POST['setting']) && is_array($_POST['setting'])) { - if (User::hasPermission('superadmin')) { - // Build variables for specific sub-settings - $qry_insert = ''; - $qry_values = ''; - foreach ($this->qry_extra as $item) { - $qry_insert = ', ' . $item['name']; - $qry_values = ', :' . $item['name']; - } - // Load all existing config options to validate input - $res = Database::simpleQuery('SELECT setting, validator FROM setting'); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $key = $row['setting']; - $validator = $row['validator']; - $displayValue = (isset($_POST['setting'][$key]) ? $_POST['setting'][$key] : ''); - // Validate data first! - $mangledValue = Validator::validate($validator, $displayValue); - if ($mangledValue === false) { - Message::addWarning('value-invalid', $key, $displayValue); - continue; - } - // Now put into DB - Database::exec("INSERT INTO setting_global (setting, value, displayvalue $qry_insert) - VALUES (:key, :value, :displayvalue $qry_values) - ON DUPLICATE KEY UPDATE value = :value, displayvalue = :displayvalue", - $this->qry_extra + array( - 'key' => $key, - 'value' => $mangledValue, - 'displayvalue' => $displayValue - ) - ); - } - Message::addSuccess('settings-updated'); - Util::redirect('?do=BaseConfig'); - } - } - } - - protected function doRender() - { - if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - Util::redirect('?do=Main'); - } - // Build left joins for specific settings - $joins = ''; - foreach ($this->qry_extra as $item) { - $joins .= " LEFT JOIN {$item['table']} "; - } - // List global config option - $settings = array(); - $res = Database::simpleQuery('SELECT cat_setting.catid, setting.setting, setting.defaultvalue, setting.permissions, setting.validator, tbl.displayvalue - FROM setting - INNER JOIN cat_setting USING (catid) - LEFT JOIN setting_global AS tbl USING (setting) - ORDER BY cat_setting.sortval ASC, setting.setting ASC'); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['description'] = Util::markup(Dictionary::translate('settings/setting', $row['setting'])); - if (is_null($row['displayvalue'])) $row['displayvalue'] = $row['defaultvalue']; - $row['item'] = $this->makeInput($row['validator'], $row['setting'], $row['displayvalue']); - $settings[$row['catid']]['settings'][] = $row; - $settings[$row['catid']]['category_name'] = Dictionary::translate('settings/cat_setting', 'cat_' . $row['catid']); - } - - Render::addTemplate('baseconfig/_page', array( - 'categories' => array_values($settings) - )); - } - - /** - * Create html snippet for setting, based on given validator - * @param type $validator - * @return boolean - */ - private function makeInput($validator, $setting, $current) - { - $parts = explode(':', $validator, 2); - if ($parts[0] === 'list') { - $items = explode('|', $parts[1]); - $ret = ''; - } - // Password field guessing - if (stripos($validator, 'password') !== false) { - $type = Property::getPasswordFieldType(); - } else { - $type = 'text'; - } - // Fallback: single line input - return ''; - } - -} diff --git a/modules/baseconfig/config.json b/modules/baseconfig/config.json new file mode 100644 index 00000000..93209f62 --- /dev/null +++ b/modules/baseconfig/config.json @@ -0,0 +1,4 @@ +{ + "category":"settings", + "enabled":"true" +} diff --git a/modules/baseconfig/module.inc.php b/modules/baseconfig/module.inc.php new file mode 100644 index 00000000..3d187d30 --- /dev/null +++ b/modules/baseconfig/module.inc.php @@ -0,0 +1,127 @@ +qry_extra[] = array( + 'name' => 'distroid', + 'value' => (int)$_REQUEST['distroid'], + 'table' => 'setting_distro', + ); + if (isset($_REQUEST['poolid'])) { + $this->qry_extra[] = array( + 'name' => 'poolid', + 'value' => (int)$_REQUEST['poolid'], + 'table' => 'setting_pool', + ); + } + } + + if (isset($_POST['setting']) && is_array($_POST['setting'])) { + if (User::hasPermission('superadmin')) { + // Build variables for specific sub-settings + $qry_insert = ''; + $qry_values = ''; + foreach ($this->qry_extra as $item) { + $qry_insert = ', ' . $item['name']; + $qry_values = ', :' . $item['name']; + } + // Load all existing config options to validate input + $res = Database::simpleQuery('SELECT setting, validator FROM setting'); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $key = $row['setting']; + $validator = $row['validator']; + $displayValue = (isset($_POST['setting'][$key]) ? $_POST['setting'][$key] : ''); + // Validate data first! + $mangledValue = Validator::validate($validator, $displayValue); + if ($mangledValue === false) { + Message::addWarning('value-invalid', $key, $displayValue); + continue; + } + // Now put into DB + Database::exec("INSERT INTO setting_global (setting, value, displayvalue $qry_insert) + VALUES (:key, :value, :displayvalue $qry_values) + ON DUPLICATE KEY UPDATE value = :value, displayvalue = :displayvalue", + $this->qry_extra + array( + 'key' => $key, + 'value' => $mangledValue, + 'displayvalue' => $displayValue + ) + ); + } + Message::addSuccess('settings-updated'); + Util::redirect('?do=BaseConfig'); + } + } + } + + protected function doRender() + { + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=Main'); + } + // Build left joins for specific settings + $joins = ''; + foreach ($this->qry_extra as $item) { + $joins .= " LEFT JOIN {$item['table']} "; + } + // List global config option + $settings = array(); + $res = Database::simpleQuery('SELECT cat_setting.catid, setting.setting, setting.defaultvalue, setting.permissions, setting.validator, tbl.displayvalue + FROM setting + INNER JOIN cat_setting USING (catid) + LEFT JOIN setting_global AS tbl USING (setting) + ORDER BY cat_setting.sortval ASC, setting.setting ASC'); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['description'] = Util::markup(Dictionary::translate('settings/setting', $row['setting'])); + if (is_null($row['displayvalue'])) $row['displayvalue'] = $row['defaultvalue']; + $row['item'] = $this->makeInput($row['validator'], $row['setting'], $row['displayvalue']); + $settings[$row['catid']]['settings'][] = $row; + $settings[$row['catid']]['category_name'] = Dictionary::translate('settings/cat_setting', 'cat_' . $row['catid']); + $settings[$row['catid']]['category_id'] = $row['catid']; + } + Render::addTemplate('_page', array( + 'categories' => array_values($settings) + )); + } + + /** + * Create html snippet for setting, based on given validator + * @param type $validator + * @return boolean + */ + private function makeInput($validator, $setting, $current) + { + $parts = explode(':', $validator, 2); + if ($parts[0] === 'list') { + $items = explode('|', $parts[1]); + $ret = ''; + } + // Password field guessing + if (stripos($validator, 'password') !== false) { + $type = Property::getPasswordFieldType(); + } else { + $type = 'text'; + } + // Fallback: single line input + return ''; + } + +} diff --git a/modules/baseconfig/templates/_page.html b/modules/baseconfig/templates/_page.html new file mode 100644 index 00000000..c72f0a5e --- /dev/null +++ b/modules/baseconfig/templates/_page.html @@ -0,0 +1,186 @@ +

{{lang_basicConfiguration}}

+

{{lang_clientRelatedConfig}}

+
+
+ + + {{#categories}} +
+ +
+
+
+ {{#settings}} +
+
+
+ +
+
+ {{setting}} +
{{defaultvalue}}
+
+
+ {{{item}}} +
+
+ +
+
+
+ + {{/settings}} +
+
+ +
+
+
+
+ {{/categories}} + + + + +
+ +
+
+
+ {{#users}} +
+
+
+ +
+
+ +
+ +
+
+ {{/users}} +
+
+
+
+
+ + + + Download +
+

+

+ + + +
+

+ +
+ + + +
+ +
+ + + +
+ diff --git a/modules/citymanagement/config.json b/modules/citymanagement/config.json new file mode 100644 index 00000000..3cd4afd3 --- /dev/null +++ b/modules/citymanagement/config.json @@ -0,0 +1,5 @@ +{ + "category":"hidden", + "enabled":"false", + "permission":"0" +} diff --git a/modules/citymanagement/module.inc.php b/modules/citymanagement/module.inc.php new file mode 100644 index 00000000..acc30bf9 --- /dev/null +++ b/modules/citymanagement/module.inc.php @@ -0,0 +1,81 @@ +page = $p; + else + $this->page = 1; + switch(Request::post('action')){ + case "edit": + $this->edit(Request::post('cityid'),Request::post('name')); + break; + case "create": + $this->create(Request::post('name')); + break; + case "delete": + $this->delete(Request::post('cityid')); + break; + } + + + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=Main'); + } + + } + + protected function doRender() + { + // load every city + $cities = array(); + $res = Database::simpleQuery("SELECT cityid, name FROM cities ORDER BY cityid DESC"); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $cities[] = array( + 'id' => $row['cityid'], + 'name' => $row['name'], + ); + } + + $pag = new Pagination($cities,$this->page); + + Render::addTemplate('page-citymanagement', array( + 'cities' => $pag->getItems(), + 'pages' => $pag->getPagination() + )); + } + + private function edit($cityid, $newname){ + $data = array ( + 'cityid' => $cityid, + 'name' => $newname, + ); + Database::exec ( 'UPDATE cities SET name = :name WHERE cityid = :cityid', $data ); + Message::addSuccess('update-city'); + } + + private function create($name){ + $data = array ( + 'name' => $name, + ); + Database::exec('INSERT INTO cities(name) VALUES( :name )',$data); + Message::addSuccess('add-city'); + } + + private function delete($cityid){ + $data = array ( + 'cityid' => $cityid + ); + Database::exec ( 'DELETE FROM cities WHERE cityid = :cityid', $data ); + Message::addSuccess('delete-city'); + } +} diff --git a/modules/citymanagement/templates/page-citymanagement.html b/modules/citymanagement/templates/page-citymanagement.html new file mode 100644 index 00000000..6d7750cf --- /dev/null +++ b/modules/citymanagement/templates/page-citymanagement.html @@ -0,0 +1,77 @@ +
+
+
{{lang_cityPage}}
+
+
+

+ {{lang_cityInfo}} +

+ +
+ + + + + + + + + + + + + + + {{#cities}} + + + + + + {{/cities}} + + + +
ID{{lang_cityname}}{{lang_operations}}
+ +
+ + + +
+
    + {{#pages}} +
  • {{page}}
  • + {{/pages}} +
+
+
+{{#cities}} + +{{/cities}} diff --git a/modules/dozmod.inc.php b/modules/dozmod.inc.php deleted file mode 100644 index 98cacd59..00000000 --- a/modules/dozmod.inc.php +++ /dev/null @@ -1,252 +0,0 @@ -mailHandler(); - } - if ($action === 'delimages') { - $result = $this->handleDeleteImages(); - if (!empty($result)) { - Message::addInfo('delete-images', $result); - } - Util::redirect('?do=DozMod'); - } - } - - protected function doRender() - { - $this->listDeletePendingImages(); - // Mail config - $conf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig')); - if ($conf != null) { - $conf = @json_decode($conf['value'], true); - if (is_array($conf)) { - $conf['set_' . $conf['ssl']] = 'selected="selected"'; - } - } - Render::addTemplate('dozmod/mailconfig', $conf); - // User list for making people admin - $this->listUsers(); - $this->listOrganizations(); - } - - private function listDeletePendingImages() - { - $res = Database::simpleQuery("SELECT b.displayname," - . " own.firstname, own.lastname, own.email," - . " v.imageversionid, v.createtime, v.filesize, v.deletestate," - . " lat.expiretime AS latexptime, lat.deletestate AS latdelstate" - . " FROM sat.imageversion v" - . " INNER JOIN sat.imagebase b ON (b.imagebaseid = v.imagebaseid)" - . " INNER JOIN sat.user own ON (b.ownerid = own.userid)" - . " LEFT JOIN sat.imageversion lat ON (b.latestversionid = lat.imageversionid)" - . " WHERE v.deletestate <> 'KEEP'" - . " ORDER BY b.displayname ASC, v.createtime ASC"); - $NOW = time(); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($row['latexptime'] > $NOW && $row['latdelstate'] === 'KEEP') { - $row['hasNewerClass'] = 'glyphicon-ok green'; - } else { - $row['hasNewerClass'] = 'glyphicon-remove red'; - } - if ($row['deletestate'] === 'WANT_DELETE') { - $row['name_extra_class'] = 'slx-strike'; - } - $row['version'] = date('d.m.Y H:i:s', $row['createtime']); - $row['filesize'] = Util::readableFileSize($row['filesize']); - $rows[] = $row; - } - if (empty($rows)) - return; - Render::addTemplate('dozmod/images-delete', array('images' => $rows)); - } - - private function cleanMailArray() - { - $keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName'); - $data = array(); - foreach ($keys as $key) { - $data[$key] = Request::post($key, ''); - settype($data[$key], 'string'); - if (is_numeric($data[$key])) { - settype($data[$key], 'int'); - } - } - return $data; - } - - protected function doAjax() - { - if (!User::hasPermission('superadmin')) - return; - - $action = Request::post('action'); - if ($action === 'mail') { - $this->handleTestMail(); - } elseif ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') { - $this->setUserOption($action); - } elseif ($action === 'setorglogin') { - $this->setOrgOption($action); - } elseif ($action === 'delimages') { - die($this->handleDeleteImages()); - } - } - - private function handleDeleteImages() - { - $images = Request::post('images', false); - if (is_array($images)) { - foreach ($images as $image => $val) { - if (strtolower($val) !== 'on') - continue; - Database::exec("UPDATE sat.imageversion SET deletestate = 'WANT_DELETE'" - . " WHERE deletestate = 'SHOULD_DELETE' AND imageversionid = :imageversionid", array( - 'imageversionid' => $image - )); - } - if (!empty($images)) { - $ret = Download::asStringPost('http://127.0.0.1:9080/do/delete-images', false, 2, $code); - if ($code == 999) { - $ret .= "\nConnection to DMSD failed."; - } - return $ret; - } - } - return false; - } - - private function handleTestMail() - { - $do = Request::post('button'); - if ($do === 'test') { - // Prepare array - $data = $this->cleanMailArray(); - Header('Content-Type: text/plain; charset=utf-8'); - $data['recipient'] = Request::post('recipient', ''); - if (!preg_match('/.+@.+\..+/', $data['recipient'])) { - $result = 'No recipient given!'; - } else { - $result = Download::asStringPost('http://127.0.0.1:9080/do/mailtest', $data, 2, $code); - } - die($result); - } - } - - private function mailHandler() - { - // Check action - $do = Request::post('button'); - if ($do === 'save') { - // Prepare array - $data = $this->cleanMailArray(); - $data = json_encode($data); - Database::exec('INSERT INTO sat.configuration (parameter, value)' - . ' VALUES (:param, :value)' - . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array( - 'param' => 'mailconfig', - 'value' => $data - )); - Message::addSuccess('mail-config-saved'); - } - Util::redirect('?do=DozMod'); - } - - private function listUsers() - { - $res = Database::simpleQuery('SELECT userid, firstname, lastname, email, lastlogin, user.canlogin, issuperuser, emailnotifications,' - . ' organization.displayname AS orgname FROM sat.user' - . ' LEFT JOIN sat.organization USING (organizationid)' - . ' ORDER BY lastname ASC, firstname ASC'); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['canlogin'] = $this->checked($row['canlogin']); - $row['issuperuser'] = $this->checked($row['issuperuser']); - $row['emailnotifications'] = $this->checked($row['emailnotifications']); - $row['lastlogin'] = date('d.m.Y', $row['lastlogin']); - $rows[] = $row; - } - Render::addTemplate('dozmod/userlist', array('users' => $rows)); - } - - private function listOrganizations() - { - $res = Database::simpleQuery('SELECT organizationid, displayname, canlogin FROM sat.organization' - . ' ORDER BY displayname ASC'); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['canlogin'] = $this->checked($row['canlogin']); - $rows[] = $row; - } - Render::addTemplate('dozmod/orglist', array('organizations' => $rows)); - } - - private function checked($val) - { - if ($val) - return 'checked="checked"'; - return ''; - } - - private function setUserOption($option) - { - $val = (string) Request::post('value', '-'); - if ($val !== '1' && $val !== '0') - die('Nein'); - if ($option === 'setmail') { - $field = 'emailnotifications'; - } elseif ($option === 'setsu') { - $field = 'issuperuser'; - } elseif ($option === 'setlogin') { - $field = 'canlogin'; - } else { - die('Unknown'); - } - $user = (string) Request::post('userid', '?'); - $ret = Database::exec("UPDATE sat.user SET $field = :onoff WHERE userid = :userid", array( - 'userid' => $user, - 'onoff' => $val - )); - error_log("Setting $field to $val for $user - affected: $ret"); - if ($ret === false) - die('Error'); - if ($ret == 0) - die(1 - $val); - die($val); - } - - private function setOrgOption($option) - { - $val = (string) Request::post('value', '-'); - if ($val !== '1' && $val !== '0') - die('Nein'); - if ($option === 'setorglogin') { - $field = 'canlogin'; - } else { - die('Unknown'); - } - $ret = Database::exec("UPDATE sat.organization SET $field = :onoff WHERE organizationid = :organizationid", array( - 'organizationid' => (string) Request::post('organizationid', ''), - 'onoff' => $val - )); - if ($ret === false) - die('Error'); - if ($ret === 0) - die(1 - $val); - die($val); - } - -} diff --git a/modules/dozmod/config.json b/modules/dozmod/config.json new file mode 100644 index 00000000..4e7fa5fb --- /dev/null +++ b/modules/dozmod/config.json @@ -0,0 +1,4 @@ +{ + "category":"content", + "enabled":"true" +} diff --git a/modules/dozmod/module.inc.php b/modules/dozmod/module.inc.php new file mode 100644 index 00000000..f98d8952 --- /dev/null +++ b/modules/dozmod/module.inc.php @@ -0,0 +1,252 @@ +mailHandler(); + } + if ($action === 'delimages') { + $result = $this->handleDeleteImages(); + if (!empty($result)) { + Message::addInfo('delete-images', $result); + } + Util::redirect('?do=DozMod'); + } + } + + protected function doRender() + { + $this->listDeletePendingImages(); + // Mail config + $conf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig')); + if ($conf != null) { + $conf = @json_decode($conf['value'], true); + if (is_array($conf)) { + $conf['set_' . $conf['ssl']] = 'selected="selected"'; + } + } + Render::addTemplate('mailconfig', $conf); + // User list for making people admin + $this->listUsers(); + $this->listOrganizations(); + } + + private function listDeletePendingImages() + { + $res = Database::simpleQuery("SELECT b.displayname," + . " own.firstname, own.lastname, own.email," + . " v.imageversionid, v.createtime, v.filesize, v.deletestate," + . " lat.expiretime AS latexptime, lat.deletestate AS latdelstate" + . " FROM sat.imageversion v" + . " INNER JOIN sat.imagebase b ON (b.imagebaseid = v.imagebaseid)" + . " INNER JOIN sat.user own ON (b.ownerid = own.userid)" + . " LEFT JOIN sat.imageversion lat ON (b.latestversionid = lat.imageversionid)" + . " WHERE v.deletestate <> 'KEEP'" + . " ORDER BY b.displayname ASC, v.createtime ASC"); + $NOW = time(); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['latexptime'] > $NOW && $row['latdelstate'] === 'KEEP') { + $row['hasNewerClass'] = 'glyphicon-ok green'; + } else { + $row['hasNewerClass'] = 'glyphicon-remove red'; + } + if ($row['deletestate'] === 'WANT_DELETE') { + $row['name_extra_class'] = 'slx-strike'; + } + $row['version'] = date('d.m.Y H:i:s', $row['createtime']); + $row['filesize'] = Util::readableFileSize($row['filesize']); + $rows[] = $row; + } + if (empty($rows)) + return; + Render::addTemplate('images-delete', array('images' => $rows)); + } + + private function cleanMailArray() + { + $keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName'); + $data = array(); + foreach ($keys as $key) { + $data[$key] = Request::post($key, ''); + settype($data[$key], 'string'); + if (is_numeric($data[$key])) { + settype($data[$key], 'int'); + } + } + return $data; + } + + protected function doAjax() + { + if (!User::hasPermission('superadmin')) + return; + + $action = Request::post('action'); + if ($action === 'mail') { + $this->handleTestMail(); + } elseif ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') { + $this->setUserOption($action); + } elseif ($action === 'setorglogin') { + $this->setOrgOption($action); + } elseif ($action === 'delimages') { + die($this->handleDeleteImages()); + } + } + + private function handleDeleteImages() + { + $images = Request::post('images', false); + if (is_array($images)) { + foreach ($images as $image => $val) { + if (strtolower($val) !== 'on') + continue; + Database::exec("UPDATE sat.imageversion SET deletestate = 'WANT_DELETE'" + . " WHERE deletestate = 'SHOULD_DELETE' AND imageversionid = :imageversionid", array( + 'imageversionid' => $image + )); + } + if (!empty($images)) { + $ret = Download::asStringPost('http://127.0.0.1:9080/do/delete-images', false, 2, $code); + if ($code == 999) { + $ret .= "\nConnection to DMSD failed."; + } + return $ret; + } + } + return false; + } + + private function handleTestMail() + { + $do = Request::post('button'); + if ($do === 'test') { + // Prepare array + $data = $this->cleanMailArray(); + Header('Content-Type: text/plain; charset=utf-8'); + $data['recipient'] = Request::post('recipient', ''); + if (!preg_match('/.+@.+\..+/', $data['recipient'])) { + $result = 'No recipient given!'; + } else { + $result = Download::asStringPost('http://127.0.0.1:9080/do/mailtest', $data, 2, $code); + } + die($result); + } + } + + private function mailHandler() + { + // Check action + $do = Request::post('button'); + if ($do === 'save') { + // Prepare array + $data = $this->cleanMailArray(); + $data = json_encode($data); + Database::exec('INSERT INTO sat.configuration (parameter, value)' + . ' VALUES (:param, :value)' + . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array( + 'param' => 'mailconfig', + 'value' => $data + )); + Message::addSuccess('mail-config-saved'); + } + Util::redirect('?do=DozMod'); + } + + private function listUsers() + { + $res = Database::simpleQuery('SELECT userid, firstname, lastname, email, lastlogin, user.canlogin, issuperuser, emailnotifications,' + . ' organization.displayname AS orgname FROM sat.user' + . ' LEFT JOIN sat.organization USING (organizationid)' + . ' ORDER BY lastname ASC, firstname ASC'); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['canlogin'] = $this->checked($row['canlogin']); + $row['issuperuser'] = $this->checked($row['issuperuser']); + $row['emailnotifications'] = $this->checked($row['emailnotifications']); + $row['lastlogin'] = date('d.m.Y', $row['lastlogin']); + $rows[] = $row; + } + Render::addTemplate('userlist', array('users' => $rows)); + } + + private function listOrganizations() + { + $res = Database::simpleQuery('SELECT organizationid, displayname, canlogin FROM sat.organization' + . ' ORDER BY displayname ASC'); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['canlogin'] = $this->checked($row['canlogin']); + $rows[] = $row; + } + Render::addTemplate('orglist', array('organizations' => $rows)); + } + + private function checked($val) + { + if ($val) + return 'checked="checked"'; + return ''; + } + + private function setUserOption($option) + { + $val = (string) Request::post('value', '-'); + if ($val !== '1' && $val !== '0') + die('Nein'); + if ($option === 'setmail') { + $field = 'emailnotifications'; + } elseif ($option === 'setsu') { + $field = 'issuperuser'; + } elseif ($option === 'setlogin') { + $field = 'canlogin'; + } else { + die('Unknown'); + } + $user = (string) Request::post('userid', '?'); + $ret = Database::exec("UPDATE sat.user SET $field = :onoff WHERE userid = :userid", array( + 'userid' => $user, + 'onoff' => $val + )); + error_log("Setting $field to $val for $user - affected: $ret"); + if ($ret === false) + die('Error'); + if ($ret == 0) + die(1 - $val); + die($val); + } + + private function setOrgOption($option) + { + $val = (string) Request::post('value', '-'); + if ($val !== '1' && $val !== '0') + die('Nein'); + if ($option === 'setorglogin') { + $field = 'canlogin'; + } else { + die('Unknown'); + } + $ret = Database::exec("UPDATE sat.organization SET $field = :onoff WHERE organizationid = :organizationid", array( + 'organizationid' => (string) Request::post('organizationid', ''), + 'onoff' => $val + )); + if ($ret === false) + die('Error'); + if ($ret === 0) + die(1 - $val); + die($val); + } + +} diff --git a/modules/dozmod/templates/images-delete.html b/modules/dozmod/templates/images-delete.html new file mode 100644 index 00000000..c4cbfd34 --- /dev/null +++ b/modules/dozmod/templates/images-delete.html @@ -0,0 +1,57 @@ +

{{lang_heading}}

+ +
+
+ {{lang_subHeading}} +
+
+

{{lang_description}}

+
+
+ + + + + + + + + + + + + + + {{#images}} + + + + + + + + + {{/images}} + +
{{lang_image}}{{lang_version}}{{lang_owner}}{{lang_size}}
{{displayname}}
{{imageversionid}}
{{version}}{{lastname}}, {{firstname}}{{filesize}}
+ +
+ +
+
+
+ + \ No newline at end of file diff --git a/modules/dozmod/templates/mailconfig.html b/modules/dozmod/templates/mailconfig.html new file mode 100644 index 00000000..b19776c0 --- /dev/null +++ b/modules/dozmod/templates/mailconfig.html @@ -0,0 +1,91 @@ +

{{lang_mailConfigHeadline}}

+ +
+
+ {{lang_mailConfig}} +
+
+

{{lang_mailDescription}}

+

[BETA] Diese FunktionalitÃĪt ist neu. Wir bitten um Nachsicht, falls es Situationen gibt, in denen zu viele + oder zu wenige Nachrichten verschickt werden.

+
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+

{{lang_asteriskRequired}}

+
+

{{lang_testConfiguration}}

+
+ + +
+
+ + + + +
+ + +
+
+
+ + \ No newline at end of file diff --git a/modules/dozmod/templates/orglist.html b/modules/dozmod/templates/orglist.html new file mode 100644 index 00000000..d325cc4d --- /dev/null +++ b/modules/dozmod/templates/orglist.html @@ -0,0 +1,51 @@ +

{{lang_organizationList}}

+ +
+
+ {{lang_organizationListHeader}} +
+
+
+ + + + + + + + + {{#organizations}} + + + + + {{/organizations}} + +
{{lang_organization}}
{{displayname}}
+
+
+
+ + \ No newline at end of file diff --git a/modules/dozmod/templates/userlist.html b/modules/dozmod/templates/userlist.html new file mode 100644 index 00000000..a76eae5e --- /dev/null +++ b/modules/dozmod/templates/userlist.html @@ -0,0 +1,62 @@ +

{{lang_userList}}

+ +
+
+ {{lang_userListHeader}} +
+
+

{{lang_userListDescription}}

+
+ + + + + + + + + + + + + + {{#users}} + + + + + + + + + + {{/users}} + +
{{lang_user}}{{lang_organization}}{{lang_lastLogin}}{{lang_email}}
{{lastname}}, {{firstname}}{{orgname}}{{lastlogin}}{{email}}
+
+
+
+ + \ No newline at end of file diff --git a/modules/eventlog.inc.php b/modules/eventlog.inc.php deleted file mode 100644 index a070f5a2..00000000 --- a/modules/eventlog.inc.php +++ /dev/null @@ -1,70 +0,0 @@ -exec(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $day = date('d.m.Y', $row['dateline']); - if ($day === $today) { - $day = Dictionary::translate('today'); - } elseif ($day === $yesterday) { - $day = Dictionary::translate('yesterday'); - } - $row['date'] = $day . date(' H:i', $row['dateline']); - $row['icon'] = $this->typeToIcon($row['logtypeid']); - $row['color'] = $this->typeToColor($row['logtypeid']); - $lines[] = $row; - } - - $paginate->render('eventlog/_page', array( - 'list' => $lines - )); - } - - private function typeToIcon($type) - { - switch ($type) { - case 'info': - return 'ok'; - case 'warning': - return 'exclamation-sign'; - case 'failure': - return 'remove'; - default: - return 'question-sign'; - } - } - - private function typeToColor($type) - { - switch ($type) { - case 'info': - return ''; - case 'warning': - return 'orange'; - case 'failure': - return 'red'; - default: - return ''; - } - } - -} diff --git a/modules/eventlog/config.json b/modules/eventlog/config.json new file mode 100644 index 00000000..d42dc3e3 --- /dev/null +++ b/modules/eventlog/config.json @@ -0,0 +1,4 @@ +{ + "category":"status", + "enabled":"true" +} diff --git a/modules/eventlog/module.inc.php b/modules/eventlog/module.inc.php new file mode 100644 index 00000000..7cfc8a55 --- /dev/null +++ b/modules/eventlog/module.inc.php @@ -0,0 +1,70 @@ +exec(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $day = date('d.m.Y', $row['dateline']); + if ($day === $today) { + $day = Dictionary::translate('today'); + } elseif ($day === $yesterday) { + $day = Dictionary::translate('yesterday'); + } + $row['date'] = $day . date(' H:i', $row['dateline']); + $row['icon'] = $this->typeToIcon($row['logtypeid']); + $row['color'] = $this->typeToColor($row['logtypeid']); + $lines[] = $row; + } + + $paginate->render('_page', array( + 'list' => $lines + )); + } + + private function typeToIcon($type) + { + switch ($type) { + case 'info': + return 'ok'; + case 'warning': + return 'exclamation-sign'; + case 'failure': + return 'remove'; + default: + return 'question-sign'; + } + } + + private function typeToColor($type) + { + switch ($type) { + case 'info': + return ''; + case 'warning': + return 'orange'; + case 'failure': + return 'red'; + default: + return ''; + } + } + +} diff --git a/modules/eventlog/templates/_page.html b/modules/eventlog/templates/_page.html new file mode 100644 index 00000000..2e657805 --- /dev/null +++ b/modules/eventlog/templates/_page.html @@ -0,0 +1,41 @@ +

{{lang_eventLog}}

+{{{pagenav}}} + + + + + + + + + {{#list}} + + + + + + + {{/list}} + +
{{lang_when}}{{lang_event}}{{lang_details}}
{{date}}{{description}}{{#extra}} + » + + {{/extra}}
+{{{pagenav}}} + + diff --git a/modules/imgmanagement/config.json b/modules/imgmanagement/config.json new file mode 100644 index 00000000..49daa91a --- /dev/null +++ b/modules/imgmanagement/config.json @@ -0,0 +1,5 @@ +{ + "category":"hidden", + "enabled":"false", + "permission":"1" +} diff --git a/modules/imgmanagement/module.inc.php b/modules/imgmanagement/module.inc.php new file mode 100644 index 00000000..27844e23 --- /dev/null +++ b/modules/imgmanagement/module.inc.php @@ -0,0 +1,76 @@ +baselocation = '/var/images/'; + $this->images = array(); + + error_reporting(E_ALL); + ini_set('display_errors','on'); + + Session::get('token'); + + } + + 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); + 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); + 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 new file mode 100644 index 00000000..795ae39f --- /dev/null +++ b/modules/imgmanagement/templates/page-imgmanagement.html @@ -0,0 +1,46 @@ +
+
+ Gerenciamento de Imagens +
+ +
+
+ Imagens em azul indicam imagens criadas pelo usuÃĄrio +
+ +
+
+
    + {{#deactives}} +
  • {{name}}
  • + {{/deactives}} +
+
+
+ +
+
+
    + + {{#actives}} +
  • {{name}}
  • + {{/actives}} +
+
+
+ + Upload de Nova Imagem + Gerar IPXE + +
+
+ + + diff --git a/modules/internetaccess.inc.php b/modules/internetaccess.inc.php deleted file mode 100644 index c142285d..00000000 --- a/modules/internetaccess.inc.php +++ /dev/null @@ -1,51 +0,0 @@ -{{lang_internetAccess}} + +
+ + + +
+
{{lang_internetAccess}}
+
+

{{lang_description}}

+
+ {{lang_proxyType}} + +
+
+

{{lang_manualProxyConfig}}

+
+ {{lang_proxyAddress}} * + +
+
+ {{lang_proxyPort}} * + +
+
+ {{lang_proxyUsername}} + +
+
+ {{lang_proxyPassword}} + +
+ +
+
+
diff --git a/modules/internetaccess/templates/restart.html b/modules/internetaccess/templates/restart.html new file mode 100644 index 00000000..effe1feb --- /dev/null +++ b/modules/internetaccess/templates/restart.html @@ -0,0 +1,22 @@ +
+
{{lang_serviceRestart}}
+
+
{{lang_restarting}} syncdaemon
+
{{lang_restarting}} dmsd
+
{{lang_restarting}} ldadp
+ +
+
+ + diff --git a/modules/locations.inc.php b/modules/locations.inc.php deleted file mode 100644 index d4d0c85f..00000000 --- a/modules/locations.inc.php +++ /dev/null @@ -1,348 +0,0 @@ -action = Request::post('action'); - if ($this->action === 'updatelocation') { - $this->updateLocation(); - } elseif ($this->action === 'addlocations') { - $this->addLocations(); - } - } - - private function addLocations() - { - $names = Request::post('newlocation', false); - $parents = Request::post('newparent', false); - if (!is_array($names) || !is_array($parents)) { - Message::addError('empty-field'); - Util::redirect('?do=Locations'); - } - $locs = Location::getLocations(); - $count = 0; - foreach ($names as $idx => $name) { - $name = trim($name); - if (empty($name)) continue; - $parent = isset($parents[$idx]) ? (int)$parents[$idx] : 0; - if ($parent !== 0) { - $ok = false; - foreach ($locs as $loc) { - if ($loc['locationid'] == $parent) { - $ok = true; - } - } - if (!$ok) { - Message::addWarning('value-invalid', 'parentlocationid', $parent); - continue; - } - } - Database::exec("INSERT INTO location (parentlocationid, locationname)" - . " VALUES (:parent, :name)", array( - 'parent' => $parent, - 'name' => $name - )); - $count++; - } - Message::addSuccess('added-x-entries', $count); - Util::redirect('?do=Locations'); - } - - private function updateLocation() - { - $locationId = Request::post('locationid', false, 'integer'); - $del = Request::post('deletelocation', false, 'integer'); - if ($locationId === false) { - Message::addError('parameter-missing', 'locationid'); - Util::redirect('?do=Locations'); - } - $location = Database::queryFirst('SELECT locationid, parentlocationid, locationname FROM location' - . ' WHERE locationid = :lid', array('lid' => $locationId)); - if ($location === false) { - Message::addError('value-invalid', 'locationid', $locationId); - Util::redirect('?do=Locations'); - } - // Delete location? - if ($locationId === $del) { - $this->deleteLocation($location); - } - // Update subnets - $this->updateLocationSubnets($location); - // Insert subnets - $this->addNewLocationSubnets($location); // TODO - // Update location! - $this->updateLocationData($location); - Util::redirect('?do=Locations'); - } - - private function deleteLocation($location) - { - $locationId = (int)$location['locationid']; - $ids = $locationId; - if (Request::post('recursive', false) === 'on') { - $rows = Location::queryLocations(); - $rows = Location::buildTree($rows, $locationId); - $rows = Location::extractIds($rows); - if (!empty($rows)) { - $ids .= ',' . implode(',', $rows); - } - } - $subs = Database::exec("DELETE FROM subnet WHERE locationid IN ($ids)"); - $locs = Database::exec("DELETE FROM location WHERE locationid IN ($ids)"); - Database::exec('UPDATE location SET parentlocationid = :newparent WHERE parentlocationid = :oldparent', array( - 'newparent' => $location['parentlocationid'], - 'oldparent' => $location['locationid'] - )); - Message::addSuccess('location-deleted', $locs, $subs); - Util::redirect('?do=Locations'); - } - - private function updateLocationData($location) - { - $locationId = (int)$location['locationid']; - $newParent = Request::post('parentlocationid', false, 'integer'); - $newName = Request::post('locationname', false, 'string'); - if ($newName === false || preg_match('/^\s*$/', $newName)) { - if ($newName !== false) { - Message::addWarning('value-invalid', 'location name', $newName); - } - $newName = $location['locationname']; - } - if ($newParent === false) { - $newParent = $location['parentlocationid']; - } else if ($newParent !== 0) { - $rows = Location::queryLocations(); - $all = Location::extractIds(Location::buildTree($rows)); - if (!in_array($newParent, $all) || $newParent === $locationId) { - Message::addWarning('value-invalid', 'parent', $newParent); - $newParent = $location['parentlocationid']; - } else { - $rows = Location::extractIds(Location::buildTree($rows, $locationId)); - if (in_array($newParent, $rows)) { - Message::addWarning('value-invalid', 'parent', $newParent); - $newParent = $location['parentlocationid']; - } - } - } - $ret = Database::exec('UPDATE location SET parentlocationid = :parent, locationname = :name' - . ' WHERE locationid = :lid', array( - 'lid' => $locationId, - 'parent' => $newParent, - 'name' => $newName - )); - if ($ret > 0) { - Message::addSuccess('location-updated', $newName); - } - } - - private function updateLocationSubnets($location) - { - $locationId = (int)$location['locationid']; - // Deletion first - $dels = Request::post('deletesubnet', false); - if (is_array($dels)) { - $count = 0; - $stmt = Database::prepare('DELETE FROM subnet WHERE subnetid = :id'); - foreach ($dels as $key => $value) { - if (!is_numeric($key) || $value !== 'on') continue; - if ($stmt->execute(array('id' => $key))) { - $count += $stmt->rowCount(); - } - } - if ($count > 0) { - Message::addInfo('subnets-deleted', $count); - } - } - // Now actual updates - // TODO: Warn on mismatch/overlap (should lie entirely in parent's subnet, not overlap with others) - $starts = Request::post('startaddr', false); - $ends = Request::post('endaddr', false); - if (!is_array($starts) || !is_array($ends)) { - return; - } - $count = 0; - $stmt = Database::prepare('UPDATE subnet SET startaddr = :start, endaddr = :end' - . ' WHERE subnetid = :id'); - foreach ($starts as $key => $start) { - if (!isset($ends[$key]) || !is_numeric($key)) continue; - $end = $ends[$key]; - list($startLong, $endLong) = $this->rangeToLong($start, $end); - if ($startLong === false) { - Message::addWarning('value-invalid', 'start addr', $start); - } - if ($endLong === false) { - Message::addWarning('value-invalid', 'end addr', $start); - } - if ($startLong === false || $endLong === false) continue; - if ($startLong > $endLong) { - Message::addWarning('value-invalid', 'range', $start . ' - ' . $end); - continue; - } - if ($stmt->execute(array('id' => $key, 'start' => $startLong, 'end' => $endLong))) { - $count += $stmt->rowCount(); - } - } - if ($count > 0) { - Message::addInfo('subnets-updated', $count); - } - } - - private function addNewLocationSubnets($location) - { - $locationId = (int)$location['locationid']; - $starts = Request::post('newstartaddr', false); - $ends = Request::post('newendaddr', false); - if (!is_array($starts) || !is_array($ends)) { - return; - } - $count = 0; - $stmt = Database::prepare('INSERT INTO subnet SET startaddr = :start, endaddr = :end, locationid = :location'); - foreach ($starts as $key => $start) { - if (!isset($ends[$key]) || !is_numeric($key)) continue; - $end = $ends[$key]; - list($startLong, $endLong) = $this->rangeToLong($start, $end); - if ($startLong === false) { - Message::addWarning('value-invalid', 'new start addr', $start); - } - if ($endLong === false) { - Message::addWarning('value-invalid', 'new end addr', $start); - } - if ($startLong === false || $endLong === false) continue; - if ($startLong > $endLong) { - Message::addWarning('value-invalid', 'range', $start . ' - ' . $end); - continue; - } - if ($stmt->execute(array('location' => $locationId, 'start' => $startLong, 'end' => $endLong))) { - $count += $stmt->rowCount(); - } - } - if ($count > 0) { - Message::addInfo('subnets-created', $count); - } - } - - /* - * Rendering normal pages - */ - - protected function doRender() - { - //Render::setTitle(Dictionary::translate('lang_titleBackup')); - $getAction = Request::get('action'); - if (empty($getAction)) { - // Until we have a main landing page? - Util::redirect('?do=Locations&action=showlocations'); - } - if ($getAction === 'showsubnets') { - $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet"); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['startaddr'] = long2ip($row['startaddr']); - $row['endaddr'] = long2ip($row['endaddr']); - $row['locations'] = Location::getLocations($row['locationid']); - $rows[] = $row; - } - Render::addTemplate('locations/subnets', array('list' => $rows)); - } elseif ($getAction === 'showlocations') { - $locs = Location::getLocations(); - Render::addTemplate('locations/locations', array('list' => $locs)); - } - } - - /* - * Ajax - */ - - protected function doAjax() - { - User::load(); - if (!User::isLoggedIn()) { - die('Unauthorized'); - } - $action = Request::any('action'); - if ($action === 'showlocation') { - $this->ajaxShowLocation(); - } - } - - private function ajaxShowLocation() - { - $locationId = Request::any('locationid', 0, 'integer'); - $loc = Database::queryFirst('SELECT locationid, parentlocationid, locationname FROM location WHERE locationid = :lid', - array('lid' => $locationId)); - if ($loc === false) { - die('Unknown locationid'); - } - $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr FROM subnet WHERE locationid = :lid", - array('lid' => $locationId)); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['startaddr'] = long2ip($row['startaddr']); - $row['endaddr'] = long2ip($row['endaddr']); - $rows[] = $row; - } - $data = array( - 'locationid' => $loc['locationid'], - 'locationname' => $loc['locationname'], - 'list' => $rows, - 'parents' => Location::getLocations($loc['parentlocationid'], $locationId, true) - ); - // if (moduleEnabled(DOZMOD) { - $lectures = Database::queryFirst('SELECT Count(*) AS cnt FROM sat.lecture l ' - . ' INNER JOIN sat.lecture_x_location ll ON (l.lectureid = ll.lectureid AND ll.locationid = :lid)', - array('lid' => $locationId)); - $data['lectures'] = $lectures['cnt']; - // } - // Get clients matching this location's subnet(s) - $mres = Database::simpleQuery("SELECT lastseen, logintime FROM machine" - . " INNER JOIN subnet ON (INET_ATON(machine.clientip) BETWEEN startaddr AND endaddr)" - . " WHERE subnet.locationid = :lid OR machine.locationid = :lid", array('lid' => $locationId)); - $count = $online = $used = 0; - $DL = time() - 605; - while ($row = $mres->fetch(PDO::FETCH_ASSOC)) { - $count++; - if ($row['lastseen'] > $DL) { - $online++; - if ($row['logintime'] != 0) { - $used++; - } - } - } - $data['machines'] = $count; - $data['machines_online'] = $online; - $data['machines_used'] = $used; - $data['used_percent'] = round(100 * $used / $online); - echo Render::parse('locations/location-subnets', $data); - } - - /* - * Helpers - */ - - private function rangeToLong($start, $end) - { - $startLong = ip2long($start); - $endLong = ip2long($end); - if ($startLong !== false) { - $startLong = sprintf("%u", $startLong); - } - if ($endLong !== false) { - $endLong = sprintf("%u", $endLong); - } - return array($startLong, $endLong); - } - -} diff --git a/modules/locations/config.json b/modules/locations/config.json new file mode 100644 index 00000000..4e7fa5fb --- /dev/null +++ b/modules/locations/config.json @@ -0,0 +1,4 @@ +{ + "category":"content", + "enabled":"true" +} diff --git a/modules/locations/module.inc.php b/modules/locations/module.inc.php new file mode 100644 index 00000000..60af719b --- /dev/null +++ b/modules/locations/module.inc.php @@ -0,0 +1,348 @@ +action = Request::post('action'); + if ($this->action === 'updatelocation') { + $this->updateLocation(); + } elseif ($this->action === 'addlocations') { + $this->addLocations(); + } + } + + private function addLocations() + { + $names = Request::post('newlocation', false); + $parents = Request::post('newparent', false); + if (!is_array($names) || !is_array($parents)) { + Message::addError('empty-field'); + Util::redirect('?do=Locations'); + } + $locs = Location::getLocations(); + $count = 0; + foreach ($names as $idx => $name) { + $name = trim($name); + if (empty($name)) continue; + $parent = isset($parents[$idx]) ? (int)$parents[$idx] : 0; + if ($parent !== 0) { + $ok = false; + foreach ($locs as $loc) { + if ($loc['locationid'] == $parent) { + $ok = true; + } + } + if (!$ok) { + Message::addWarning('value-invalid', 'parentlocationid', $parent); + continue; + } + } + Database::exec("INSERT INTO location (parentlocationid, locationname)" + . " VALUES (:parent, :name)", array( + 'parent' => $parent, + 'name' => $name + )); + $count++; + } + Message::addSuccess('added-x-entries', $count); + Util::redirect('?do=Locations'); + } + + private function updateLocation() + { + $locationId = Request::post('locationid', false, 'integer'); + $del = Request::post('deletelocation', false, 'integer'); + if ($locationId === false) { + Message::addError('parameter-missing', 'locationid'); + Util::redirect('?do=Locations'); + } + $location = Database::queryFirst('SELECT locationid, parentlocationid, locationname FROM location' + . ' WHERE locationid = :lid', array('lid' => $locationId)); + if ($location === false) { + Message::addError('value-invalid', 'locationid', $locationId); + Util::redirect('?do=Locations'); + } + // Delete location? + if ($locationId === $del) { + $this->deleteLocation($location); + } + // Update subnets + $this->updateLocationSubnets($location); + // Insert subnets + $this->addNewLocationSubnets($location); // TODO + // Update location! + $this->updateLocationData($location); + Util::redirect('?do=Locations'); + } + + private function deleteLocation($location) + { + $locationId = (int)$location['locationid']; + $ids = $locationId; + if (Request::post('recursive', false) === 'on') { + $rows = Location::queryLocations(); + $rows = Location::buildTree($rows, $locationId); + $rows = Location::extractIds($rows); + if (!empty($rows)) { + $ids .= ',' . implode(',', $rows); + } + } + $subs = Database::exec("DELETE FROM subnet WHERE locationid IN ($ids)"); + $locs = Database::exec("DELETE FROM location WHERE locationid IN ($ids)"); + Database::exec('UPDATE location SET parentlocationid = :newparent WHERE parentlocationid = :oldparent', array( + 'newparent' => $location['parentlocationid'], + 'oldparent' => $location['locationid'] + )); + Message::addSuccess('location-deleted', $locs, $subs); + Util::redirect('?do=Locations'); + } + + private function updateLocationData($location) + { + $locationId = (int)$location['locationid']; + $newParent = Request::post('parentlocationid', false, 'integer'); + $newName = Request::post('locationname', false, 'string'); + if ($newName === false || preg_match('/^\s*$/', $newName)) { + if ($newName !== false) { + Message::addWarning('value-invalid', 'location name', $newName); + } + $newName = $location['locationname']; + } + if ($newParent === false) { + $newParent = $location['parentlocationid']; + } else if ($newParent !== 0) { + $rows = Location::queryLocations(); + $all = Location::extractIds(Location::buildTree($rows)); + if (!in_array($newParent, $all) || $newParent === $locationId) { + Message::addWarning('value-invalid', 'parent', $newParent); + $newParent = $location['parentlocationid']; + } else { + $rows = Location::extractIds(Location::buildTree($rows, $locationId)); + if (in_array($newParent, $rows)) { + Message::addWarning('value-invalid', 'parent', $newParent); + $newParent = $location['parentlocationid']; + } + } + } + $ret = Database::exec('UPDATE location SET parentlocationid = :parent, locationname = :name' + . ' WHERE locationid = :lid', array( + 'lid' => $locationId, + 'parent' => $newParent, + 'name' => $newName + )); + if ($ret > 0) { + Message::addSuccess('location-updated', $newName); + } + } + + private function updateLocationSubnets($location) + { + $locationId = (int)$location['locationid']; + // Deletion first + $dels = Request::post('deletesubnet', false); + if (is_array($dels)) { + $count = 0; + $stmt = Database::prepare('DELETE FROM subnet WHERE subnetid = :id'); + foreach ($dels as $key => $value) { + if (!is_numeric($key) || $value !== 'on') continue; + if ($stmt->execute(array('id' => $key))) { + $count += $stmt->rowCount(); + } + } + if ($count > 0) { + Message::addInfo('subnets-deleted', $count); + } + } + // Now actual updates + // TODO: Warn on mismatch/overlap (should lie entirely in parent's subnet, not overlap with others) + $starts = Request::post('startaddr', false); + $ends = Request::post('endaddr', false); + if (!is_array($starts) || !is_array($ends)) { + return; + } + $count = 0; + $stmt = Database::prepare('UPDATE subnet SET startaddr = :start, endaddr = :end' + . ' WHERE subnetid = :id'); + foreach ($starts as $key => $start) { + if (!isset($ends[$key]) || !is_numeric($key)) continue; + $end = $ends[$key]; + list($startLong, $endLong) = $this->rangeToLong($start, $end); + if ($startLong === false) { + Message::addWarning('value-invalid', 'start addr', $start); + } + if ($endLong === false) { + Message::addWarning('value-invalid', 'end addr', $start); + } + if ($startLong === false || $endLong === false) continue; + if ($startLong > $endLong) { + Message::addWarning('value-invalid', 'range', $start . ' - ' . $end); + continue; + } + if ($stmt->execute(array('id' => $key, 'start' => $startLong, 'end' => $endLong))) { + $count += $stmt->rowCount(); + } + } + if ($count > 0) { + Message::addInfo('subnets-updated', $count); + } + } + + private function addNewLocationSubnets($location) + { + $locationId = (int)$location['locationid']; + $starts = Request::post('newstartaddr', false); + $ends = Request::post('newendaddr', false); + if (!is_array($starts) || !is_array($ends)) { + return; + } + $count = 0; + $stmt = Database::prepare('INSERT INTO subnet SET startaddr = :start, endaddr = :end, locationid = :location'); + foreach ($starts as $key => $start) { + if (!isset($ends[$key]) || !is_numeric($key)) continue; + $end = $ends[$key]; + list($startLong, $endLong) = $this->rangeToLong($start, $end); + if ($startLong === false) { + Message::addWarning('value-invalid', 'new start addr', $start); + } + if ($endLong === false) { + Message::addWarning('value-invalid', 'new end addr', $start); + } + if ($startLong === false || $endLong === false) continue; + if ($startLong > $endLong) { + Message::addWarning('value-invalid', 'range', $start . ' - ' . $end); + continue; + } + if ($stmt->execute(array('location' => $locationId, 'start' => $startLong, 'end' => $endLong))) { + $count += $stmt->rowCount(); + } + } + if ($count > 0) { + Message::addInfo('subnets-created', $count); + } + } + + /* + * Rendering normal pages + */ + + protected function doRender() + { + //Render::setTitle(Dictionary::translate('lang_titleBackup')); + $getAction = Request::get('action'); + if (empty($getAction)) { + // Until we have a main landing page? + Util::redirect('?do=Locations&action=showlocations'); + } + if ($getAction === 'showsubnets') { + $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet"); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['startaddr'] = long2ip($row['startaddr']); + $row['endaddr'] = long2ip($row['endaddr']); + $row['locations'] = Location::getLocations($row['locationid']); + $rows[] = $row; + } + Render::addTemplate('subnets', array('list' => $rows)); + } elseif ($getAction === 'showlocations') { + $locs = Location::getLocations(); + Render::addTemplate('locations', array('list' => $locs)); + } + } + + /* + * Ajax + */ + + protected function doAjax() + { + User::load(); + if (!User::isLoggedIn()) { + die('Unauthorized'); + } + $action = Request::any('action'); + if ($action === 'showlocation') { + $this->ajaxShowLocation(); + } + } + + private function ajaxShowLocation() + { + $locationId = Request::any('locationid', 0, 'integer'); + $loc = Database::queryFirst('SELECT locationid, parentlocationid, locationname FROM location WHERE locationid = :lid', + array('lid' => $locationId)); + if ($loc === false) { + die('Unknown locationid'); + } + $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr FROM subnet WHERE locationid = :lid", + array('lid' => $locationId)); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['startaddr'] = long2ip($row['startaddr']); + $row['endaddr'] = long2ip($row['endaddr']); + $rows[] = $row; + } + $data = array( + 'locationid' => $loc['locationid'], + 'locationname' => $loc['locationname'], + 'list' => $rows, + 'parents' => Location::getLocations($loc['parentlocationid'], $locationId, true) + ); + // if (moduleEnabled(DOZMOD) { + $lectures = Database::queryFirst('SELECT Count(*) AS cnt FROM sat.lecture l ' + . ' INNER JOIN sat.lecture_x_location ll ON (l.lectureid = ll.lectureid AND ll.locationid = :lid)', + array('lid' => $locationId)); + $data['lectures'] = $lectures['cnt']; + // } + // Get clients matching this location's subnet(s) + $mres = Database::simpleQuery("SELECT lastseen, logintime FROM machine" + . " INNER JOIN subnet ON (INET_ATON(machine.clientip) BETWEEN startaddr AND endaddr)" + . " WHERE subnet.locationid = :lid OR machine.locationid = :lid", array('lid' => $locationId)); + $count = $online = $used = 0; + $DL = time() - 605; + while ($row = $mres->fetch(PDO::FETCH_ASSOC)) { + $count++; + if ($row['lastseen'] > $DL) { + $online++; + if ($row['logintime'] != 0) { + $used++; + } + } + } + $data['machines'] = $count; + $data['machines_online'] = $online; + $data['machines_used'] = $used; + $data['used_percent'] = round(100 * $used / $online); + echo Render::parse('location-subnets', $data); + } + + /* + * Helpers + */ + + private function rangeToLong($start, $end) + { + $startLong = ip2long($start); + $endLong = ip2long($end); + if ($startLong !== false) { + $startLong = sprintf("%u", $startLong); + } + if ($endLong !== false) { + $endLong = sprintf("%u", $endLong); + } + return array($startLong, $endLong); + } + +} diff --git a/modules/locations/templates/location-subnets.html b/modules/locations/templates/location-subnets.html new file mode 100644 index 00000000..76b7442a --- /dev/null +++ b/modules/locations/templates/location-subnets.html @@ -0,0 +1,73 @@ +
\ No newline at end of file diff --git a/modules/locations/templates/locations.html b/modules/locations/templates/locations.html new file mode 100644 index 00000000..76c8f97c --- /dev/null +++ b/modules/locations/templates/locations.html @@ -0,0 +1,96 @@ +
+ +

{{lang_locationsMainHeading}}

+ + + + + + + {{#list}} + + + + + + {{/list}} +
#{{lang_locationName}}
{{locationid}}
{{locationname}}
+ {{lang_edit}} +
+
+ + + + + + + + +
+ + + +
+
+
+ diff --git a/modules/locations/templates/subnets.html b/modules/locations/templates/subnets.html new file mode 100644 index 00000000..2294f42b --- /dev/null +++ b/modules/locations/templates/subnets.html @@ -0,0 +1,35 @@ +
+ +

{{lang_listOfSubnets}}

+
+ + + + + + + + + + {{#list}} + + + + + + + {{/list}} +
#{{lang_startAddress}}{{lang_endAddress}}{{lang_location}}
{{subnetid}} + +
+
+ +
+
+
diff --git a/modules/main.inc.php b/modules/main.inc.php deleted file mode 100644 index 9af1afef..00000000 --- a/modules/main.inc.php +++ /dev/null @@ -1,54 +0,0 @@ -sysconfig = !file_exists(CONFIG_HTTP_DIR . '/default/config.tgz'); - $this->minilinux = !file_exists(CONFIG_HTTP_DIR . '/default/kernel') || !file_exists(CONFIG_HTTP_DIR . '/default/initramfs-stage31') || !file_exists(CONFIG_HTTP_DIR . '/default/stage32.sqfs'); - $this->vmstore = !is_array(Property::getVmStoreConfig()); - $this->ipxe = !preg_match('/^\d+\.\d+\.\d+\.\d+$/', Property::getServerIp()); - Property::setNeedsSetup(($this->sysconfig || $this->minilinux || $this->vmstore || $this->ipxe) ? 1 : 0); - $res = Database::queryFirst("SELECT Count(*) AS cnt FROM sat.imageversion WHERE deletestate = 'SHOULD_DELETE'"); - $this->delPending = isset($res['cnt']) ? $res['cnt'] : 0; - } - } - - protected function doRender() - { - // Render::setTitle('abc'); - - if (!User::isLoggedIn()) { - Render::addTemplate('page-main-guest', array( - 'register' => (Database::queryFirst('SELECT userid FROM user LIMIT 1') === false) - )); - return; - } - // Logged in here - - Render::addTemplate('page-main', array( - 'user' => User::getName(), - 'sysconfig' => $this->sysconfig, - 'minilinux' => $this->minilinux, - 'vmstore' => $this->vmstore, - 'ipxe' => $this->ipxe, - 'delpending' => $this->delPending - )); - } - - protected function doAjax() - { - User::isLoggedIn(); - die('Status: DB running'); - } - -} diff --git a/modules/main/config.json b/modules/main/config.json new file mode 100644 index 00000000..d5da4cc8 --- /dev/null +++ b/modules/main/config.json @@ -0,0 +1,4 @@ +{ + "category":"hidden", + "enabled":"true" +} diff --git a/modules/main/module.inc.php b/modules/main/module.inc.php new file mode 100644 index 00000000..369d4b54 --- /dev/null +++ b/modules/main/module.inc.php @@ -0,0 +1,64 @@ +sysconfig = !file_exists(CONFIG_HTTP_DIR . '/default/config.tgz'); + $this->minilinux = !file_exists(CONFIG_HTTP_DIR . '/default/kernel') || !file_exists(CONFIG_HTTP_DIR . '/default/initramfs-stage31') || !file_exists(CONFIG_HTTP_DIR . '/default/stage32.sqfs'); + $this->vmstore = !is_array(Property::getVmStoreConfig()); + $this->ipxe = !preg_match('/^\d+\.\d+\.\d+\.\d+$/', Property::getServerIp()); + Property::setNeedsSetup(($this->sysconfig || $this->minilinux || $this->vmstore || $this->ipxe) ? 1 : 0); + $res = Database::queryFirst("SELECT Count(*) AS cnt FROM sat.imageversion WHERE deletestate = 'SHOULD_DELETE'", array(), true); + $this->delPending = isset($res['cnt']) ? $res['cnt'] : 0; + } + } + + protected function doRender() + { + // Render::setTitle('abc'); + + if (!User::isLoggedIn()) { + Render::addTemplate('page-main-guest', array( + 'register' => (Database::queryFirst('SELECT userid FROM user LIMIT 1') === false) + )); + return; + } + // Logged in here + + // Load news + $lines = array(); + $paginate = new Paginate("SELECT newsid, dateline, title, content FROM news ORDER BY dateline DESC", 10); + $res = $paginate->exec(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if(count($lines) >= 3) break; + $lines[] = $row; + } + + Render::addTemplate('page-main', array( + 'user' => User::getName(), + 'sysconfig' => $this->sysconfig, + 'minilinux' => $this->minilinux, + 'vmstore' => $this->vmstore, + 'ipxe' => $this->ipxe, + 'delpending' => $this->delPending, + 'news' => $lines + )); + } + + protected function doAjax() + { + User::isLoggedIn(); + die('Status: DB running'); + } + +} diff --git a/modules/main/templates/dialog-generic.html b/modules/main/templates/dialog-generic.html new file mode 100644 index 00000000..5face8ce --- /dev/null +++ b/modules/main/templates/dialog-generic.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/modules/main/templates/footer.html b/modules/main/templates/footer.html new file mode 100644 index 00000000..8cf71a5c --- /dev/null +++ b/modules/main/templates/footer.html @@ -0,0 +1,2 @@ +
+ \ No newline at end of file diff --git a/modules/main/templates/main-menu.html b/modules/main/templates/main-menu.html new file mode 100644 index 00000000..c4534c2f --- /dev/null +++ b/modules/main/templates/main-menu.html @@ -0,0 +1,51 @@ + + + diff --git a/modules/main/templates/main-menu.html.topnavbar b/modules/main/templates/main-menu.html.topnavbar new file mode 100644 index 00000000..8da8edd0 --- /dev/null +++ b/modules/main/templates/main-menu.html.topnavbar @@ -0,0 +1,92 @@ + + + diff --git a/modules/main/templates/messagebox-error.html b/modules/main/templates/messagebox-error.html new file mode 100644 index 00000000..873716c9 --- /dev/null +++ b/modules/main/templates/messagebox-error.html @@ -0,0 +1 @@ +
{{{message}}}
diff --git a/modules/main/templates/messagebox-info.html b/modules/main/templates/messagebox-info.html new file mode 100644 index 00000000..eb9d518a --- /dev/null +++ b/modules/main/templates/messagebox-info.html @@ -0,0 +1 @@ +
{{{message}}}
diff --git a/modules/main/templates/messagebox-success.html b/modules/main/templates/messagebox-success.html new file mode 100644 index 00000000..93674d69 --- /dev/null +++ b/modules/main/templates/messagebox-success.html @@ -0,0 +1 @@ +
{{{message}}}
diff --git a/modules/main/templates/messagebox-warning.html b/modules/main/templates/messagebox-warning.html new file mode 100644 index 00000000..b02e2e8a --- /dev/null +++ b/modules/main/templates/messagebox-warning.html @@ -0,0 +1 @@ +
{{{message}}}
diff --git a/modules/main/templates/page-login.html b/modules/main/templates/page-login.html new file mode 100644 index 00000000..247e9a55 --- /dev/null +++ b/modules/main/templates/page-login.html @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/modules/main/templates/page-main-guest.html b/modules/main/templates/page-main-guest.html new file mode 100644 index 00000000..28b0d04c --- /dev/null +++ b/modules/main/templates/page-main-guest.html @@ -0,0 +1,15 @@ +
+
+

{{lang_welcome}}

+

{{lang_introGuest}}

+ {{#register}} + + {{/register}} +

{{lang_login}} »

+
+
diff --git a/modules/main/templates/page-main.html b/modules/main/templates/page-main.html new file mode 100644 index 00000000..39e4e74e --- /dev/null +++ b/modules/main/templates/page-main.html @@ -0,0 +1,36 @@ +
+

{{lang_welcome}}, {{user}}

+

{{lang_intro}}

+ +
+ diff --git a/modules/main/templates/page-minilinux.html b/modules/main/templates/page-minilinux.html new file mode 100644 index 00000000..dc13e6b0 --- /dev/null +++ b/modules/main/templates/page-minilinux.html @@ -0,0 +1,14 @@ +
+
{{lang_listObtained}}
+
+ + \ No newline at end of file diff --git a/modules/main/templates/page-news.html b/modules/main/templates/page-news.html new file mode 100644 index 00000000..8e400498 --- /dev/null +++ b/modules/main/templates/page-news.html @@ -0,0 +1,57 @@ +
+
+ {{lang_editNews}} +
+
+

{{lang_newsIntro}}

+
+
+ + +
+
+ + +
+

{{lang_latestUpdate}}: {{latestDate}}

+ + +
+
+
+ +
+
+ {{lang_newsOld}} +
+
+
+
+ + + + + + + + + + + + {{#list}} + + + + + + + {{/list}} + +
{{lang_date}}{{lang_title}}{{lang_content}}
{{date}}{{title}}{{content}} + {{lang_show}} + +
+
+
+
+
diff --git a/modules/main/templates/page-syslog.html b/modules/main/templates/page-syslog.html new file mode 100644 index 00000000..98e94291 --- /dev/null +++ b/modules/main/templates/page-syslog.html @@ -0,0 +1,58 @@ +

{{lang_clientLog}}

+
+ +
+ {{lang_filter}} + + + {{lang_not}} + + + + +
+
+{{{pagenav}}} + + + + + + + + + + {{#list}} + + + + + + + + {{/list}} + +
{{lang_when}}{{lang_client}}{{lang_event}}{{lang_details}}
{{date}}{{clientip}}{{description}}{{#extra}} + » + + {{/extra}}
+{{{pagenav}}} + + + + diff --git a/modules/main/templates/page-vmstore.html b/modules/main/templates/page-vmstore.html new file mode 100644 index 00000000..fe2c5225 --- /dev/null +++ b/modules/main/templates/page-vmstore.html @@ -0,0 +1,111 @@ +
+ + + + +
+
+ {{lang_vmLocation}} +
+
+

{{lang_vmLocationChoose}}

+
+
+ {{lang_intern}} +
+
+ {{lang_noAdditionalInformation}} +
+
+
+
+ NFS + +
+
+ + +
+
+
+
+ CIFS +
+
+ + +
+ +
+ + {{lang_username}} + + + + {{lang_password}} + + +
+
+ +
+ + {{lang_username}} + + + + {{lang_password}} + + +
+
+
+ +
+
+
+ + + + diff --git a/modules/main/templates/pagenav.html b/modules/main/templates/pagenav.html new file mode 100644 index 00000000..93194999 --- /dev/null +++ b/modules/main/templates/pagenav.html @@ -0,0 +1,16 @@ +
    + {{#pages}} + {{#current}} +
  • {{text}} (current)
  • + {{/current}} + {{^current}} + {{#text}} +
  • {{text}}
  • + {{/text}} + {{^text}} +
  • + {{/text}} + {{/current}} + {{/pages}} +
+
\ No newline at end of file diff --git a/modules/main/templates/tm-callback-trigger.html b/modules/main/templates/tm-callback-trigger.html new file mode 100644 index 00000000..cd03a1fe --- /dev/null +++ b/modules/main/templates/tm-callback-trigger.html @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/modules/minilinux.inc.php b/modules/minilinux.inc.php deleted file mode 100644 index 0853c0db..00000000 --- a/modules/minilinux.inc.php +++ /dev/null @@ -1,128 +0,0 @@ - '?do=MiniLinux&async=true&action=list' - )); - Render::addFooter(''); - } - - protected function doAjax() - { - $data = Property::getVersionCheckInformation(); - if (!is_array($data) || !isset($data['systems'])) { - echo Render::parse('messagebox-error', array( - 'message' => 'Failed to retrieve the list: ' . print_r($data, true) - )); - return; - } - $action = Request::any('action'); - $selectedVersion = (int)Request::any('version', 0); - switch ($action) { - case 'list': - $count = 0; - foreach ($data['systems'] as &$system) { - // Get latest version, build simple array of all version numbers - $versionNumbers = array(); - $selected = false; - foreach ($system['versions'] as $version) { - if (!is_numeric($version['version']) || $version['version'] < 1) - continue; - if ($selectedVersion === 0 && ($selected === false || $selected['version'] < $version['version'])) - $selected = $version; - elseif ($version['version'] == $selectedVersion) - $selected = $version; - $versionNumbers[(int)$version['version']] = array( - 'version' => $version['version'] - ); - } - if ($selected === false) continue; // No versions for this system!? - ksort($versionNumbers); - // Mark latest version as selected - $versionNumbers[(int)$selected['version']]['selected'] = true; - // Add status information to system and its files - foreach ($selected['files'] as &$file) { - $file['uid'] = 'dlid' . $count++; - $local = CONFIG_HTTP_DIR . '/' . $system['id'] . '/' . $file['name']; - if (!file_exists($local) || filesize($local) !== $file['size'] || filemtime($local) < $file['mtime']) { - $file['fileChanged'] = true; - $system['systemChanged'] = true; - } - $taskId = Property::getDownloadTask($file['md5']); - if ($taskId !== false) { - $task = Taskmanager::status($taskId); - if (isset($task['data']['progress'])) { - $file['download'] = Render::parse('minilinux/download', array( - 'task' => $taskId, - 'name' => $file['name'] - )); - } - } - } - unset($system['versions']); - $system['files'] = $selected['files']; - $system['version'] = $selected['version']; - } - $data['versions'] = array_values($versionNumbers); - echo Render::parse('minilinux/filelist', $data); - return; - case 'download': - $id = Request::post('id'); - $name = Request::post('name'); - if (!$id || !$name || strpos("$id$name", '/') !== false) { - echo "Invalid download request"; - return; - } - $file = false; - $gpg = 'missing'; - foreach ($data['systems'] as &$system) { - if ($system['id'] !== $id) continue; - foreach ($system['versions'] as &$version) { - if ($version['version'] != $selectedVersion) continue; - foreach ($version['files'] as &$f) { - if ($f['name'] !== $name) continue; - $file = $f; - if (!empty($f['gpg'])) $gpg = $f['gpg']; - break; - } - } - } - if ($file === false) { - echo "Nonexistent system/file: $id / $name"; - return; - } - $task = Taskmanager::submit('DownloadFile', array( - 'url' => CONFIG_REMOTE_ML . '/' . $id . '/' . $selectedVersion . '/' . $name, - 'destination' => CONFIG_HTTP_DIR . '/' . $id . '/' . $name, - 'gpg' => $gpg - )); - if (!isset($task['id'])) { - echo 'Error launching download task: ' . $task['statusCode']; - return; - } - Property::setDownloadTask($file['md5'], $task['id']); - echo Render::parse('minilinux/download', array( - 'name' => $name, - 'task' => $task['id'] - )); - return; - } - } - -} diff --git a/modules/minilinux/config.json b/modules/minilinux/config.json new file mode 100644 index 00000000..93209f62 --- /dev/null +++ b/modules/minilinux/config.json @@ -0,0 +1,4 @@ +{ + "category":"settings", + "enabled":"true" +} diff --git a/modules/minilinux/module.inc.php b/modules/minilinux/module.inc.php new file mode 100644 index 00000000..91be456e --- /dev/null +++ b/modules/minilinux/module.inc.php @@ -0,0 +1,128 @@ + '?do=MiniLinux&async=true&action=list' + )); + Render::addFooter(''); + } + + protected function doAjax() + { + $data = Property::getVersionCheckInformation(); + if (!is_array($data) || !isset($data['systems'])) { + echo Render::parse('messagebox-error', array( + 'message' => 'Failed to retrieve the list: ' . print_r($data, true) + ),'main'); + return; + } + $action = Request::any('action'); + $selectedVersion = (int)Request::any('version', 0); + switch ($action) { + case 'list': + $count = 0; + foreach ($data['systems'] as &$system) { + // Get latest version, build simple array of all version numbers + $versionNumbers = array(); + $selected = false; + foreach ($system['versions'] as $version) { + if (!is_numeric($version['version']) || $version['version'] < 1) + continue; + if ($selectedVersion === 0 && ($selected === false || $selected['version'] < $version['version'])) + $selected = $version; + elseif ($version['version'] == $selectedVersion) + $selected = $version; + $versionNumbers[(int)$version['version']] = array( + 'version' => $version['version'] + ); + } + if ($selected === false) continue; // No versions for this system!? + ksort($versionNumbers); + // Mark latest version as selected + $versionNumbers[(int)$selected['version']]['selected'] = true; + // Add status information to system and its files + foreach ($selected['files'] as &$file) { + $file['uid'] = 'dlid' . $count++; + $local = CONFIG_HTTP_DIR . '/' . $system['id'] . '/' . $file['name']; + if (!file_exists($local) || filesize($local) !== $file['size'] || filemtime($local) < $file['mtime']) { + $file['fileChanged'] = true; + $system['systemChanged'] = true; + } + $taskId = Property::getDownloadTask($file['md5']); + if ($taskId !== false) { + $task = Taskmanager::status($taskId); + if (isset($task['data']['progress'])) { + $file['download'] = Render::parse('download', array( + 'task' => $taskId, + 'name' => $file['name'] + )); + } + } + } + unset($system['versions']); + $system['files'] = $selected['files']; + $system['version'] = $selected['version']; + } + $data['versions'] = array_values($versionNumbers); + echo Render::parse('filelist', $data); + return; + case 'download': + $id = Request::post('id'); + $name = Request::post('name'); + if (!$id || !$name || strpos("$id$name", '/') !== false) { + echo "Invalid download request"; + return; + } + $file = false; + $gpg = 'missing'; + foreach ($data['systems'] as &$system) { + if ($system['id'] !== $id) continue; + foreach ($system['versions'] as &$version) { + if ($version['version'] != $selectedVersion) continue; + foreach ($version['files'] as &$f) { + if ($f['name'] !== $name) continue; + $file = $f; + if (!empty($f['gpg'])) $gpg = $f['gpg']; + break; + } + } + } + if ($file === false) { + echo "Nonexistent system/file: $id / $name"; + return; + } + $task = Taskmanager::submit('DownloadFile', array( + 'url' => CONFIG_REMOTE_ML . '/' . $id . '/' . $selectedVersion . '/' . $name, + 'destination' => CONFIG_HTTP_DIR . '/' . $id . '/' . $name, + 'gpg' => $gpg + )); + if (!isset($task['id'])) { + echo 'Error launching download task: ' . $task['statusCode']; + return; + } + Property::setDownloadTask($file['md5'], $task['id']); + echo Render::parse('download', array( + 'name' => $name, + 'task' => $task['id'] + )); + return; + } + } + +} diff --git a/modules/minilinux/templates/download.html b/modules/minilinux/templates/download.html new file mode 100644 index 00000000..2e32df5a --- /dev/null +++ b/modules/minilinux/templates/download.html @@ -0,0 +1 @@ +
{{name}}
\ No newline at end of file diff --git a/modules/minilinux/templates/filelist.html b/modules/minilinux/templates/filelist.html new file mode 100644 index 00000000..ca94f4d0 --- /dev/null +++ b/modules/minilinux/templates/filelist.html @@ -0,0 +1,77 @@ + {{#systems}} +
+
+

{{title}}

+
+
+
+ {{lang_desiredVersion}} + +
+ {{#systemChanged}} +

+ {{lang_canUpdate1}} {{title}} {{lang_canUpdate2}} +

+

{{lang_update}}

+ {{/systemChanged}} + {{^systemChanged}} +

{{lang_systemUpdated}}

+ {{/systemChanged}} +
+

{{lang_filesInVersion}} {{version}}

+
    + {{#files}} +
  • +
    +
    {{name}}
    +
    + {{^fileChanged}} {{lang_actual}}{{/fileChanged}} + {{#fileChanged}} {{lang_outdated}}{{/fileChanged}} +
    +
    + {{#fileChanged}}{{lang_update}}{{/fileChanged}} + {{^fileChanged}}{{lang_redownload}}{{/fileChanged}} +
    +
    + {{{download}}} +
  • + {{/files}} +
+
+
+ {{/systems}} + {{^systems}} +
{{lang_configurationPackageNotFound}}
+ {{/systems}} + + diff --git a/modules/minilinux/templates/page-minilinux.html b/modules/minilinux/templates/page-minilinux.html new file mode 100644 index 00000000..007e1e1b --- /dev/null +++ b/modules/minilinux/templates/page-minilinux.html @@ -0,0 +1,28 @@ +
+
{{lang_listObtained}}
+ +
+ + \ No newline at end of file diff --git a/modules/news.inc.php b/modules/news.inc.php deleted file mode 100644 index d0aa32ea..00000000 --- a/modules/news.inc.php +++ /dev/null @@ -1,167 +0,0 @@ -newsId = false; - $this->newsTitle = false; - $this->newsContent = false; - $this->newsDate = false; - } elseif ($action === 'show') { - // show news - if (!$this->loadNews(Request::any('newsid'))) { - Message::addError('news-empty'); - } - } elseif ($action === 'save') { - // save to DB - if (!$this->saveNews()) { - // re-set the fields we got - Request::post('news-title') ? $this->newsTitle = Request::post('news-title') : $this->newsTitle = false; - Request::post('news-content') ? $this->newsContent = Request::post('news-content') : $this->newsContent = false; - } else { - Message::addSuccess('news-save-success'); - Util::redirect('?do=News'); - } - } elseif ($action === 'delete') { - // delete it - $this->delNews(Request::post('newsid')); - } else { - // unknown action, redirect user - Message::addError('invalid-action', $action); - Util::redirect('?do=News'); - } - } - - /** - * Implementation of the abstract doRender function - * - * Fetch the list of news from the database and paginate it. - * - */ - protected function doRender() - { - // fetch the list of the older news - $lines = array(); - $paginate = new Paginate("SELECT newsid, dateline, title, content FROM news ORDER BY dateline DESC", 10); - $res = $paginate->exec(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['date'] = date('d.m.Y H:i', $row['dateline']); - - if ($row['newsid'] == $this->newsId) $row['active'] = "active"; - $lines[] = $row; - } - $paginate->render('page-news', array( - 'token' => Session::get('token'), - 'latestDate' => ($this->newsDate ? date('d.m.Y H:i', $this->newsDate) : '--'), - 'latestContent' => $this->newsContent, - 'latestTitle' => $this->newsTitle, - 'list' => $lines )); - - } - /** - * Loads the news with the given ID into the form. - * - * @param int $newsId ID of the news to be shown. - * @return boolean true if loading that news worked - * - */ - private function loadNews($newsId) - { - // check to see if we need to request a specific newsid - if ($newsId !== false) { - $row = Database::queryFirst("SELECT newsid, title, content, dateline FROM news WHERE newsid = :newsid LIMIT 1", array( - 'newsid' => $newsId - )); - } else { - $row = Database::queryFirst("SELECT newsid, title, content, dateline FROM news ORDER BY dateline DESC LIMIT 1"); - } - - // fetch the news to be shown - if ($row !== false) { - $this->newsId = $row['newsid']; - $this->newsTitle = $row['title']; - $this->newsContent = $row['content']; - $this->newsDate = $row['dateline']; - } - return $row !== false; - } - - /** - * Save the given $newsTitle and $newsContent as POST'ed into the database. - * - */ - private function saveNews() - { - // check if news content were set by the user - $newsTitle = Request::post('news-title'); - $newsContent = Request::post('news-content'); - if ($newsContent !== '' && $newsTitle !== '') { - // we got title and content, save it to DB - Database::exec("INSERT INTO news (dateline, title, content) VALUES (:dateline, :title, :content)", array( - 'dateline' => time(), - 'title' => $newsTitle, - 'content' => $newsContent - )); - return true; - } else { - Message::addError('empty-field'); - return false; - } - } - - /** - * Delete the news entry with ID $newsId - * - * @param int $newsId ID of the entry to be deleted. - */ - private function delNews($newsId) - { - // sanity check: is newsId even numeric? - if (!is_numeric($newsId)) { - Message::addError('value-invalid', 'newsid', $newsId); - } else { - // check passed - do delete - Database::exec("DELETE FROM news WHERE newsid = :newsid LIMIT 1", array( - 'newsid' => $newsId - )); - Message::addSuccess('news-del-success'); - } - Util::redirect('?do=News'); - } - -} diff --git a/modules/news/config.json b/modules/news/config.json new file mode 100644 index 00000000..4e7fa5fb --- /dev/null +++ b/modules/news/config.json @@ -0,0 +1,4 @@ +{ + "category":"content", + "enabled":"true" +} diff --git a/modules/news/module.inc.php b/modules/news/module.inc.php new file mode 100644 index 00000000..9bbadc4f --- /dev/null +++ b/modules/news/module.inc.php @@ -0,0 +1,167 @@ +newsId = false; + $this->newsTitle = false; + $this->newsContent = false; + $this->newsDate = false; + } elseif ($action === 'show') { + // show news + if (!$this->loadNews(Request::any('newsid'))) { + Message::addError('news-empty'); + } + } elseif ($action === 'save') { + // save to DB + if (!$this->saveNews()) { + // re-set the fields we got + Request::post('news-title') ? $this->newsTitle = Request::post('news-title') : $this->newsTitle = false; + Request::post('news-content') ? $this->newsContent = Request::post('news-content') : $this->newsContent = false; + } else { + Message::addSuccess('news-save-success'); + Util::redirect('?do=News'); + } + } elseif ($action === 'delete') { + // delete it + $this->delNews(Request::post('newsid')); + } else { + // unknown action, redirect user + Message::addError('invalid-action', $action); + Util::redirect('?do=News'); + } + } + + /** + * Implementation of the abstract doRender function + * + * Fetch the list of news from the database and paginate it. + * + */ + protected function doRender() + { + // fetch the list of the older news + $lines = array(); + $paginate = new Paginate("SELECT newsid, dateline, title, content FROM news ORDER BY dateline DESC", 10); + $res = $paginate->exec(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['date'] = date('d.m.Y H:i', $row['dateline']); + + if ($row['newsid'] == $this->newsId) $row['active'] = "active"; + $lines[] = $row; + } + $paginate->render('page-news', array( + 'token' => Session::get('token'), + 'latestDate' => ($this->newsDate ? date('d.m.Y H:i', $this->newsDate) : '--'), + 'latestContent' => $this->newsContent, + 'latestTitle' => $this->newsTitle, + 'list' => $lines )); + + } + /** + * Loads the news with the given ID into the form. + * + * @param int $newsId ID of the news to be shown. + * @return boolean true if loading that news worked + * + */ + private function loadNews($newsId) + { + // check to see if we need to request a specific newsid + if ($newsId !== false) { + $row = Database::queryFirst("SELECT newsid, title, content, dateline FROM news WHERE newsid = :newsid LIMIT 1", array( + 'newsid' => $newsId + )); + } else { + $row = Database::queryFirst("SELECT newsid, title, content, dateline FROM news ORDER BY dateline DESC LIMIT 1"); + } + + // fetch the news to be shown + if ($row !== false) { + $this->newsId = $row['newsid']; + $this->newsTitle = $row['title']; + $this->newsContent = $row['content']; + $this->newsDate = $row['dateline']; + } + return $row !== false; + } + + /** + * Save the given $newsTitle and $newsContent as POST'ed into the database. + * + */ + private function saveNews() + { + // check if news content were set by the user + $newsTitle = Request::post('news-title'); + $newsContent = Request::post('news-content'); + if ($newsContent !== '' && $newsTitle !== '') { + // we got title and content, save it to DB + Database::exec("INSERT INTO news (dateline, title, content) VALUES (:dateline, :title, :content)", array( + 'dateline' => time(), + 'title' => $newsTitle, + 'content' => $newsContent + )); + return true; + } else { + Message::addError('empty-field'); + return false; + } + } + + /** + * Delete the news entry with ID $newsId + * + * @param int $newsId ID of the entry to be deleted. + */ + private function delNews($newsId) + { + // sanity check: is newsId even numeric? + if (!is_numeric($newsId)) { + Message::addError('value-invalid', 'newsid', $newsId); + } else { + // check passed - do delete + Database::exec("DELETE FROM news WHERE newsid = :newsid LIMIT 1", array( + 'newsid' => $newsId + )); + Message::addSuccess('news-del-success'); + } + Util::redirect('?do=News'); + } + +} \ No newline at end of file diff --git a/modules/news/templates/page-news.html b/modules/news/templates/page-news.html new file mode 100644 index 00000000..8e400498 --- /dev/null +++ b/modules/news/templates/page-news.html @@ -0,0 +1,57 @@ +
+
+ {{lang_editNews}} +
+
+

{{lang_newsIntro}}

+
+
+ + +
+
+ + +
+

{{lang_latestUpdate}}: {{latestDate}}

+ + +
+
+
+ +
+
+ {{lang_newsOld}} +
+
+
+
+ + + + + + + + + + + + {{#list}} + + + + + + + {{/list}} + +
{{lang_date}}{{lang_title}}{{lang_content}}
{{date}}{{title}}{{content}} + {{lang_show}} + +
+
+
+
+
diff --git a/modules/serversetup.inc.php b/modules/serversetup.inc.php deleted file mode 100644 index 87ebfdad..00000000 --- a/modules/serversetup.inc.php +++ /dev/null @@ -1,141 +0,0 @@ -currentMenu = Property::getBootMenu(); - - $action = Request::post('action'); - - if ($action === false) { - $this->currentAddress = Property::getServerIp(); - $this->getLocalAddresses(); - } - - if ($action === 'ip') { - // New address is to be set - $this->getLocalAddresses(); - $this->updateLocalAddress(); - } - - if ($action === 'ipxe') { - // iPXE stuff changes - $this->updatePxeMenu(); - } - } - - protected function doRender() - { - Render::setTitle(Dictionary::translate('lang_serverConfiguration')); - - $taskid = Request::any('taskid'); - if ($taskid !== false && Taskmanager::isTask($taskid)) { - Render::addTemplate('serversetup/ipxe_update', array('taskid' => $taskid)); - } - - Render::addTemplate('serversetup/ipaddress', array( - 'ips' => $this->taskStatus['data']['addresses'], - 'chooseHintClass' => $this->hasIpSet ? '' : 'alert alert-danger' - )); - $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('serversetup/ipxe', $data); - } - - // ----------------------------------------------------------------------------------------------- - - private function getLocalAddresses() - { - $this->taskStatus = Taskmanager::submit('LocalAddressesList', array()); - - if ($this->taskStatus === false) { - $this->taskStatus['data']['addresses'] = false; - return false; - } - - if ($this->taskStatus['statusCode'] === TASK_WAITING) { // TODO: Async if just displaying - $this->taskStatus = Taskmanager::waitComplete($this->taskStatus['id']); - } - - $sortIp = array(); - foreach (array_keys($this->taskStatus['data']['addresses']) as $key) { - $item = & $this->taskStatus['data']['addresses'][$key]; - if (!isset($item['ip']) || !preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $item['ip']) || substr($item['ip'], 0, 4) === '127.') { - unset($this->taskStatus['data']['addresses'][$key]); - continue; - } - if ($this->currentAddress === $item['ip']) { - $item['default'] = true; - $this->hasIpSet = true; - } - $sortIp[] = $item['ip']; - } - unset($item); - array_multisort($sortIp, SORT_STRING, $this->taskStatus['data']['addresses']); - return true; - } - - private function updateLocalAddress() - { - $newAddress = Request::post('ip', 'none'); - $valid = false; - foreach ($this->taskStatus['data']['addresses'] as $item) { - if ($item['ip'] !== $newAddress) - continue; - $valid = true; - break; - } - if ($valid) { - Property::setServerIp($newAddress); - global $tidIpxe; - if (isset($tidIpxe) && $tidIpxe !== false) - Util::redirect('?do=ServerSetup&taskid=' . $tidIpxe); - } else { - Message::addError('invalid-ip', $newAddress); - } - Util::redirect(); - } - - private function updatePxeMenu() - { - $timeout = Request::post('timeout', 10); - if ($timeout === '') - $timeout = 0; - if (!is_numeric($timeout) || $timeout < 0) { - Message::addError('value-invalid', 'timeout', $timeout); - } - $this->currentMenu['defaultentry'] = Request::post('defaultentry', 'net'); - $this->currentMenu['timeout'] = $timeout; - $this->currentMenu['custom'] = Request::post('custom', ''); - $this->currentMenu['masterpasswordclear'] = Request::post('masterpassword', ''); - if (empty($this->currentMenu['masterpasswordclear'])) - $this->currentMenu['masterpassword'] = 'invalid'; - else - $this->currentMenu['masterpassword'] = Crypto::hash6($this->currentMenu['masterpasswordclear']); - Property::setBootMenu($this->currentMenu); - $id = Trigger::ipxe(); - Util::redirect('?do=ServerSetup&taskid=' . $id); - } - -} diff --git a/modules/serversetup/config.json b/modules/serversetup/config.json new file mode 100644 index 00000000..93209f62 --- /dev/null +++ b/modules/serversetup/config.json @@ -0,0 +1,4 @@ +{ + "category":"settings", + "enabled":"true" +} diff --git a/modules/serversetup/module.inc.php b/modules/serversetup/module.inc.php new file mode 100644 index 00000000..e37d7d40 --- /dev/null +++ b/modules/serversetup/module.inc.php @@ -0,0 +1,186 @@ +currentMenu = Property::getBootMenu(); + + if(Request::get('download') !== false){ + $this->downloadIpxe(Request::get('download')); + } + + if(Request::get('defaultIpxe') !== false){ + $this->defaultIpxe(Request::get('defaultIpxe')); + } + + $action = Request::post('action'); + + if ($action === false) { + $this->currentAddress = Property::getServerIp(); + $this->getLocalAddresses(); + } + + if ($action === 'ip') { + // New address is to be set + $this->getLocalAddresses(); + $this->updateLocalAddress(); + } + + if ($action === 'ipxe') { + // iPXE stuff changes + $this->updatePxeMenu(); + } + + if($action === 'save-script') { + // Save new iPXE script + $this->updateIpxeScript(); + } + + if($action === 'default-script') { + // Restore iPXE script to default + $this->defaultIpxe(); + } + } + + protected function doRender() + { + Render::setTitle(Dictionary::translate('lang_serverConfiguration')); + + $taskid = Request::any('taskid'); + if ($taskid !== false && Taskmanager::isTask($taskid)) { + 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); + } + + // ----------------------------------------------------------------------------------------------- + + private function getLocalAddresses() + { + $this->taskStatus = Taskmanager::submit('LocalAddressesList', array()); + + if ($this->taskStatus === false) { + $this->taskStatus['data']['addresses'] = false; + return false; + } + + if ($this->taskStatus['statusCode'] === TASK_WAITING) { // TODO: Async if just displaying + $this->taskStatus = Taskmanager::waitComplete($this->taskStatus['id']); + } + + $sortIp = array(); + foreach (array_keys($this->taskStatus['data']['addresses']) as $key) { + $item = & $this->taskStatus['data']['addresses'][$key]; + if (!isset($item['ip']) || !preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $item['ip']) || substr($item['ip'], 0, 4) === '127.') { + unset($this->taskStatus['data']['addresses'][$key]); + continue; + } + if ($this->currentAddress === $item['ip']) { + $item['default'] = true; + } + $sortIp[] = $item['ip']; + } + unset($item); + array_multisort($sortIp, SORT_STRING, $this->taskStatus['data']['addresses']); + return true; + } + + private function updateLocalAddress() + { + $newAddress = Request::post('ip', 'none'); + $valid = false; + foreach ($this->taskStatus['data']['addresses'] as $item) { + if ($item['ip'] !== $newAddress) + continue; + $valid = true; + break; + } + if ($valid) { + Property::setServerIp($newAddress); + global $tidIpxe; + if (isset($tidIpxe) && $tidIpxe !== false) + Util::redirect('?do=ServerSetup&taskid=' . $tidIpxe); + } else { + Message::addError('invalid-ip', $newAddress); + } + Util::redirect(); + } + + private function updatePxeMenu() + { + $timeout = Request::post('timeout', 10); + if ($timeout === '') + $timeout = 0; + if (!is_numeric($timeout) || $timeout < 0) { + Message::addError('value-invalid', 'timeout', $timeout); + } + $this->currentMenu['defaultentry'] = Request::post('defaultentry', 'net'); + $this->currentMenu['timeout'] = $timeout; + $this->currentMenu['custom'] = Request::post('custom', ''); + $this->currentMenu['masterpasswordclear'] = Request::post('masterpassword', ''); + if (empty($this->currentMenu['masterpasswordclear'])) + $this->currentMenu['masterpassword'] = 'invalid'; + else + $this->currentMenu['masterpassword'] = Crypto::hash6($this->currentMenu['masterpasswordclear']); + Property::setBootMenu($this->currentMenu); + $id = Trigger::ipxe(); + Util::redirect('?do=ServerSetup&taskid=' . $id); + } + + private function downloadIpxe($ipxe){ + $file = '/opt/taskmanager/data/ipxe/src/bin/ipxe.' . $ipxe; + if (file_exists($file)) { + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename='.basename($file)); + header('Expires: 0'); + header('Cache-Control: must-revalidate'); + header('Pragma: public'); + header('Content-Length: ' . filesize($file)); + ob_clean(); + flush(); + readfile($file); + exit(); + } + } + + private function updateIpxeScript(){ + $newScript = Request::post('custom-script'); + file_put_contents("/opt/taskmanager/data/pxe.embed",$newScript); + Util::redirect('?do=ServerSetup'); + } + + private function defaultIpxe(){ + $default = file_get_contents("/opt/taskmanager/data/pxe_default.embed"); + $default = str_replace("{{ip}}", "http://" . Property::getServerIp(), $default); + file_put_contents("/opt/taskmanager/data/pxe.embed",$default); + Util::redirect('?do=ServerSetup'); + } +} diff --git a/modules/serversetup/templates/ipaddress.html b/modules/serversetup/templates/ipaddress.html new file mode 100644 index 00000000..e4967703 --- /dev/null +++ b/modules/serversetup/templates/ipaddress.html @@ -0,0 +1,34 @@ +
+
+ {{lang_bootAddress}} +
+
+

+ {{lang_chooseIP}} +

+
+ + + + {{#ips}} + + + {{#default}} + + {{/default}} + {{^default}} + + {{/default}} + + {{/ips}} +
{{ip}} + {{lang_active}} + + +
+

+ {{lang_bootHint}} +

+
+
+
\ No newline at end of file diff --git a/modules/serversetup/templates/ipxe.html b/modules/serversetup/templates/ipxe.html new file mode 100644 index 00000000..54d7db16 --- /dev/null +++ b/modules/serversetup/templates/ipxe.html @@ -0,0 +1,149 @@ +
+
+ {{lang_mountIpxe}} +
+
+

{{lang_ipxeInfo}}

+ + +
+
+ + + + + +
+ +
+
+ + + +
+
+ +
+ +
+ + + + +
+
+ {{lang_bootMenu}} +
+
+

+ {{lang_bootInfo}} +

+
+ +
+ {{lang_bootBehavior}} +
+
+
+
+ +
+ {{lang_menuDisplayTime}} +
+ + {{lang_seconds}} +
+
+ +
+ {{lang_masterPassword}} +
+ +
+ {{lang_masterPasswordHelp}} +
+ +
+ {{lang_menuCustom}} + +
+
+ + +
+
+ + + + + + diff --git a/modules/serversetup/templates/ipxe_update.html b/modules/serversetup/templates/ipxe_update.html new file mode 100644 index 00000000..9c598667 --- /dev/null +++ b/modules/serversetup/templates/ipxe_update.html @@ -0,0 +1,20 @@ +
+
{{lang_menuGeneration}}
+
+
{{lang_menuGeneration}}
+ +
+
+ + diff --git a/modules/session.inc.php b/modules/session.inc.php deleted file mode 100644 index 5b9bc7fc..00000000 --- a/modules/session.inc.php +++ /dev/null @@ -1,38 +0,0 @@ - + + + + + + {{lang_register}} + + \ No newline at end of file diff --git a/modules/statistics.inc.php b/modules/statistics.inc.php deleted file mode 100644 index dbac4b75..00000000 --- a/modules/statistics.inc.php +++ /dev/null @@ -1,785 +0,0 @@ - $uuid, - 'text' => $text - )); - Message::addSuccess('notes-saved'); - Util::redirect('?do=Statistics&uuid=' . $uuid); - } - } - - protected function doRender() - { - Render::setTitle(Dictionary::translate('lang_titleClientStatistics')); - $uuid = Request::get('uuid', false, 'string'); - if ($uuid !== false) { - $this->showMachine($uuid); - return; - } - $filter = Request::get('filter', false, 'string'); - if ($filter !== false) { - $argument = Request::get('argument', false, 'string'); - $this->showMachineList($filter, $argument); - return; - } - Render::addScriptBottom('chart.min'); - Render::openTag('div', array('class' => 'row')); - $this->showSummary(); - $this->showMemory(); - $this->showId44(); - $this->showKvmState(); - $this->showLatestMachines(); - $this->showSystemModels(); - Render::closeTag('div'); - } - - private function capChart(&$json, $cutoff, $minSlice = 0.015) - { - $total = 0; - foreach ($json as $entry) { - $total += $entry['value']; - } - $cap = ceil($total * $cutoff); - $accounted = 0; - $id = 0; - foreach ($json as $entry) { - if (($accounted >= $cap || $entry['value'] / $total < $minSlice) && $id >= 3) break; - $id++; - $accounted += $entry['value']; - } - $json = array_slice($json, 0, $id); - if ($accounted / $total < 0.99) { - $json[] = array( - 'color' => '#eee', - 'label' => 'invalid', - 'value' => ($total - $accounted) - ); - } - } - - private function showSummary() - { - $cutoff = time() - 86400 * 30; - $online = time() - 610; - $known = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE lastseen > $cutoff"); - $on = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE lastseen > $online"); - $used = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE lastseen > $online AND logintime <> 0"); - $hdd = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE badsectors > 10 AND lastseen > $cutoff"); - $data = array( - 'known' => $known['val'], - 'online' => $on['val'], - 'used' => $used['val'], - 'usedpercent' => round($used['val'] / $on['val'] * 100), - 'badhdd' => $hdd['val'] - ); - // Graph - $cutoff = time() - 2*86400; - $res = Database::simpleQuery("SELECT dateline, data FROM statistic WHERE typeid = '~stats' AND dateline > $cutoff ORDER BY dateline ASC"); - $labels = array(); - $points1 = array('data' => array(), 'label' => 'Online', 'fillColor' => '#efe', 'strokeColor' => '#aea', 'pointColor' => '#7e7', 'pointStrokeColor' => '#fff', 'pointHighlightFill' => '#fff', 'pointHighlightStroke' => '#7e7'); - $points2 = array('data' => array(), 'label' => 'In use', 'fillColor' => '#fee', 'strokeColor' => '#eaa', 'pointColor' => '#e77', 'pointStrokeColor' => '#fff', 'pointHighlightFill' => '#fff', 'pointHighlightStroke' => '#e77'); - $sum = 0; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $x = explode('#', $row['data']); - if ($sum === 0) { - $labels[] = date('H:i', $row['dateline']); - } else { - $x[1] = max($x[1], array_pop($points1['data'])); - $x[2] = max($x[2], array_pop($points2['data'])); - } - $points1['data'][] = $x[1]; - $points2['data'][] = $x[2]; - $sum++; - if ($sum === 12) { - $sum = 0; - } - } - $data['json'] = json_encode(array('labels' => $labels, 'datasets' => array($points1, $points2))); - // Draw - Render::addTemplate('statistics/summary', $data); - } - - private function showSystemModels() - { - global $STATS_COLORS; - $res = Database::simpleQuery("SELECT systemmodel, Round(AVG(realcores)) AS cores, Count(*) AS `count` FROM machine" - . " GROUP BY systemmodel ORDER BY `count` DESC, systemmodel ASC"); - $lines = array(); - $json = array(); - $id = 0; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if (empty($row['systemmodel'])) continue; - settype($row['count'], 'integer'); - $row['id'] = 'systemid' . $id; - $row['urlsystemmodel'] = urlencode($row['systemmodel']); - $lines[] = $row; - $json[] = array( - 'color' => $STATS_COLORS[$id % count($STATS_COLORS)], - 'label' => 'systemid' . $id, - 'value' => $row['count'] - ); - ++$id; - } - $this->capChart($json, 0.92); - Render::addTemplate('statistics/cpumodels', array('rows' => $lines, 'json' => json_encode($json))); - } - - private function showMemory() - { - global $STATS_COLORS, $SIZE_RAM; - $res = Database::simpleQuery("SELECT mbram, Count(*) AS `count` FROM machine GROUP BY mbram"); - $lines = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $gb = ceil($row['mbram'] / 1024); - for ($i = 1; $i < count($SIZE_RAM); ++$i) { - if ($SIZE_RAM[$i] < $gb) continue; - if ($SIZE_RAM[$i] - $gb >= $gb - $SIZE_RAM[$i-1]) --$i; - $gb = $SIZE_RAM[$i]; - break; - } - if (isset($lines[$gb])) { - $lines[$gb] += $row['count']; - } else { - $lines[$gb] = $row['count']; - } - } - asort($lines); - $data = array('rows' => array()); - $json = array(); - $id = 0; - foreach (array_reverse($lines, true) as $k => $v) { - $data['rows'][] = array('gb' => $k, 'count' => $v, 'class' => $this->ramColorClass($k * 1024)); - $json[] = array( - 'color' => $STATS_COLORS[$id % count($STATS_COLORS)], - 'label' => (string)$k, - 'value' => $v - ); - ++$id; - } - $this->capChart($json, 0.92); - $data['json'] = json_encode($json); - Render::addTemplate('statistics/memory', $data); - } - - private function showKvmState() - { - $colors = array('UNKNOWN' => '#666', 'UNSUPPORTED' => '#ea5', 'DISABLED' => '#e55', 'ENABLED' => '#6d6'); - $res = Database::simpleQuery("SELECT kvmstate, Count(*) AS `count` FROM machine GROUP BY kvmstate ORDER BY `count` DESC"); - $lines = array(); - $json = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $lines[] = $row; - $json[] = array( - 'color' => isset($colors[$row['kvmstate']]) ? $colors[$row['kvmstate']] : '#000', - 'label' => $row['kvmstate'], - 'value' => $row['count'] - ); - } - Render::addTemplate('statistics/kvmstate', array('rows' => $lines, 'json' => json_encode($json))); - } - - private function showId44() - { - global $STATS_COLORS, $SIZE_ID44; - $res = Database::simpleQuery("SELECT id44mb, Count(*) AS `count` FROM machine GROUP BY id44mb"); - $lines = array(); - $total = 0; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $total += $row['count']; - $gb = ceil($row['id44mb'] / 1024); - for ($i = 1; $i < count($SIZE_ID44); ++$i) { - if ($SIZE_ID44[$i] < $gb) continue; - if ($SIZE_ID44[$i] - $gb >= $gb - $SIZE_ID44[$i-1]) --$i; - $gb = $SIZE_ID44[$i]; - break; - } - if (isset($lines[$gb])) { - $lines[$gb] += $row['count']; - } else { - $lines[$gb] = $row['count']; - } - } - asort($lines); - $data = array('rows' => array()); - $json = array(); - $id = 0; - foreach (array_reverse($lines, true) as $k => $v) { - $data['rows'][] = array('gb' => $k, 'count' => $v, 'class' => $this->hddColorClass($k)); - if ($k === 0) { - $color = '#e55'; - } else { - $color = $STATS_COLORS[$id++ % count($STATS_COLORS)]; - } - $json[] = array( - 'color' => $color, - 'label' => (string)$k, - 'value' => $v - ); - } - $this->capChart($json, 0.95); - $data['json'] = json_encode($json); - Render::addTemplate('statistics/id44', $data); - } - - private function showLatestMachines() - { - $data = array('cutoff' => ceil(time() / 3600) * 3600 - 86400 * 7); - $res = Database::simpleQuery("SELECT machineuuid, clientip, hostname, firstseen, mbram, kvmstate, id44mb FROM machine" - . " WHERE firstseen > :cutoff ORDER BY firstseen DESC LIMIT 32", $data); - $rows = array(); - $count = 0; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if (empty($row['hostname'])) { - $row['hostname'] = $row['clientip']; - } - $row['firstseen'] = date('d.m. H:i', $row['firstseen']); - $row['gbram'] = round(round($row['mbram'] / 500) / 2, 1); // Trial and error until we got "expected" rounding.. - $row['gbtmp'] = round($row['id44mb'] / 1024); - $row['ramclass'] = $this->ramColorClass($row['mbram']); - $row['kvmclass'] = $this->kvmColorClass($row['kvmstate']); - $row['hddclass'] = $this->hddColorClass($row['gbtmp']); - $row['kvmicon'] = $row['kvmstate'] === 'ENABLED' ? '✓' : '✗'; - if (++$count > 5) { - $row['style'] = 'display:none'; - } - $rows[] = $row; - } - Render::addTemplate('statistics/newclients', array('rows' => $rows, 'openbutton' => $count > 5)); - } - - private function showMachineList($filter, $argument) - { - global $SIZE_RAM, $SIZE_ID44; - $join = ''; - $filters = array('cpumodel', 'realcores', 'kvmstate', 'clientip', 'macaddr', 'machineuuid', 'systemmodel'); - if (in_array($filter, $filters)) { - // Simple filters mapping into db - $where = " $filter = :argument"; - $args = array('argument' => $argument); - } elseif ($filter === 'gbram') { - // Memory by rounded GB - $lower = floor($this->findBestValue($SIZE_RAM, $argument, false) * 1024 - 100); - $upper = ceil($this->findBestValue($SIZE_RAM, $argument, true) * 1024 + 100); - $where = " mbram BETWEEN $lower AND $upper"; - $args = array(); - } elseif ($filter === 'hddgb') { - // HDD by rounded GB - $lower = floor($this->findBestValue($SIZE_ID44, $argument, false) * 1024 - 100); - $upper = ceil($this->findBestValue($SIZE_ID44, $argument, true) * 1024 + 100); - $where = " id44mb BETWEEN $lower AND $upper"; - $args = array(); - } elseif ($filter === 'subnet') { - $argument = preg_replace('/[^0-9\.:]/', '', $argument); - $where = " clientip LIKE '$argument%'"; - $args = array(); - } elseif ($filter === 'badsectors') { - $where = " badsectors >= :argument "; - $args = array('argument' => $argument); - } elseif ($filter === 'state') { - if ( $argument === 'on') { - $where = " lastseen + 600 > UNIX_TIMESTAMP() "; - } elseif ($argument === 'off') { - $where = " lastseen + 600 < UNIX_TIMESTAMP() "; - } elseif ($argument === 'idle') { - $where = " lastseen + 600 > UNIX_TIMESTAMP() AND logintime = 0 "; - } elseif ($argument === 'occupied') { - $where = " lastseen + 600 > UNIX_TIMESTAMP() AND logintime <> 0 "; - } else { - Message::addError('invalid-filter'); - return; - } - } elseif ($filter === 'location') { - $where = "subnet.locationid = :lid OR machine.locationid = :lid"; - $join = " INNER JOIN subnet ON (INET_ATON(clientip) BETWEEN startaddr AND endaddr) "; - $args = array('lid' => (int)$argument); - } else { - Message::addError('invalid-filter'); - return; - } - $res = Database::simpleQuery("SELECT machineuuid, macaddr, clientip, firstseen, lastseen," - . " logintime, lastboot, realcores, mbram, kvmstate, cpumodel, id44mb, hostname, notes IS NOT NULL AS hasnotes, badsectors FROM machine" - . " $join WHERE $where ORDER BY lastseen DESC, clientip ASC", $args); - $rows = array(); - $NOW = time(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($NOW - $row['lastseen'] > 610) { - $row['state_off'] = true; - } elseif ($row['logintime'] == 0) { - $row['state_idle'] = true; - } else { - $row['state_occupied'] = true; - } - //$row['firstseen'] = date('d.m.Y H:i', $row['firstseen']); - $row['lastseen'] = date('d.m. H:i', $row['lastseen']); - //$row['lastboot'] = date('d.m. H:i', $row['lastboot']); - $row['gbram'] = round(round($row['mbram'] / 500) / 2, 1); // Trial and error until we got "expected" rounding.. - $row['gbtmp'] = round($row['id44mb'] / 1024); - $octets = explode('.', $row['clientip']); - if (count($octets) === 4) { - $row['subnet'] = "$octets[0].$octets[1].$octets[2]."; - $row['lastoctet'] = $octets[3]; - } - $row['ramclass'] = $this->ramColorClass($row['mbram']); - $row['kvmclass'] = $this->kvmColorClass($row['kvmstate']); - $row['hddclass'] = $this->hddColorClass($row['gbtmp']); - if (empty($row['hostname'])) $row['hostname'] = $row['clientip']; - $rows[] = $row; - } - Render::addTemplate('statistics/clientlist', array('rows' => $rows, 'filter' => $filter, 'argument' => $argument)); - } - - private function ramColorClass($mb) - { - if ($mb < 1500) - return 'danger'; - if ($mb < 2500) - return 'warning'; - return ''; - } - - private function kvmColorClass($state) - { - if ($state === 'DISABLED') - return 'danger'; - if ($state === 'UNKNOWN' || $state === 'UNSUPPORTED') - return 'warning'; - return ''; - } - - private function hddColorClass($gb) - { - if ($gb < 7) - return 'danger'; - if ($gb < 25) - return 'warning'; - return ''; - } - - private function findBestValue($array, $value, $up) - { - $best = 0; - for ($i = 0; $i < count($array); ++$i) { - if (abs($array[$i] - $value) < abs($array[$best] - $value)) { - $best = $i; - } - } - if (!$up && $best === 0) { - return $array[0]; - } - if ($up && $best + 1 === count($array)) { - return $array[$best]; - } - if ($up) { - return ($array[$best] + $array[$best + 1]) / 2; - } - return ($array[$best] + $array[$best - 1]) / 2; - } - - private function fillSessionInfo(&$row) - { - $res = Database::simpleQuery("SELECT dateline, username, data FROM statistic" - . " WHERE clientip = :ip AND typeid = '.vmchooser-session-name'" - . " AND dateline BETWEEN :start AND :end", array( - 'ip' => $row['clientip'], - 'start' => $row['logintime'] - 60, - 'end' => $row['logintime'] + 300 - )); - $session = false; - while ($r = $res->fetch(PDO::FETCH_ASSOC)) { - if ($session === false || abs($session['dateline'] - $row['logintime']) > abs($r['dateline'] - $row['logintime'])) { - $session = $r; - } - } - if ($session !== false) { - $row['session'] = $session['data']; - $row['username'] = $session['username']; - } - } - - private function showMachine($uuid) - { - $client = Database::queryFirst("SELECT machineuuid, macaddr, clientip, firstseen, lastseen, logintime, lastboot," - . " mbram, kvmstate, cpumodel, id44mb, data, hostname, notes FROM machine WHERE machineuuid = :uuid", - array('uuid' => $uuid)); - // Mangle fields - $NOW = time(); - if ($NOW - $client['lastseen'] > 610) { - $client['state_off'] = true; - } elseif ($client['logintime'] == 0) { - $client['state_idle'] = true; - } else { - $client['state_occupied'] = true; - $this->fillSessionInfo($client); - } - $client['firstseen_s'] = date('d.m.Y H:i', $client['firstseen']); - $client['lastseen_s'] = date('d.m.Y H:i', $client['lastseen']); - $uptime = $NOW - $client['lastboot']; - $client['lastboot_s'] = date('d.m.Y H:i', $client['lastboot']) . ' (Up ' . floor($uptime / 86400) . 'd ' . gmdate('H:i', $uptime) . ')'; - $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']); - $client['gbram'] = round(round($client['mbram'] / 500) / 2, 1); - $client['gbtmp'] = round($client['id44mb'] / 1024); - $client['ramclass'] = $this->ramColorClass($client['mbram']); - $client['kvmclass'] = $this->kvmColorClass($client['kvmstate']); - $client['hddclass'] = $this->hddColorClass($client['gbtmp']); - // Parse the giant blob of data - $hdds = array(); - if (preg_match_all('/##### ([^#]+) #+$(.*?)^#####/ims', $client['data'] . '########', $out, PREG_SET_ORDER)) { - foreach ($out as $section) { - if ($section[1] === 'CPU') { - $this->parseCpu($client, $section[2]); - } - if ($section[1] === 'dmidecode') { - $this->parseDmiDecode($client, $section[2]); - } - if ($section[1] === 'Partition tables') { - $this->parseHdd($hdds, $section[2]); - } - if (isset($hdds['hdds']) && $section[1] === 'smartctl') { - // This currently required that the partition table section comes first... - $this->parseSmartctl($hdds['hdds'], $section[2]); - } - } - } - unset($client['data']); - // Throw output at user - Render::addTemplate('statistics/machine-main', $client); - // Sessions - $NOW = time(); - $cutoff = $NOW - 86400 * 7; - //if ($cutoff < $client['firstseen']) $cutoff = $client['firstseen']; - $scale = 100 / ($NOW - $cutoff); - $res = Database::simpleQuery("SELECT dateline, typeid, data FROM statistic" - . " WHERE dateline > :cutoff AND typeid IN ('~session-length', '~offline-length') AND machineuuid = :uuid ORDER BY dateline ASC", array( - 'cutoff' => $cutoff - 86400 * 14, - 'uuid' => $uuid - )); - $spans['rows'] = array(); - $spans['graph'] = ''; - $last = false; - $first = true; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($first && $row['dateline'] > $cutoff && $client['lastboot'] > $cutoff) { - // Special case: offline before - $spans['graph'] .= '
 
'; - } - $first = false; - if ($row['dateline'] + $row['data'] < $cutoff || $row['data'] > 864000) continue; - if ($last !== false && abs($last['dateline'] - $row['dateline']) < 30 - && abs($last['data'] - $row['data']) < 30) continue; - if ($last !== false && $last['dateline'] + $last['data'] > $row['dateline']) { - $point = $last['dateline'] + $last['data']; - $row['data'] -= ($point - $row['dateline']); - $row['dateline'] = $point; - } - if ($row['dateline'] < $cutoff) { - $row['data'] -= ($cutoff - $row['dateline']); - $row['dateline'] = $cutoff; - } - $row['from'] = date('d.m. H:i', $row['dateline']); - $row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']); - if ($row['typeid'] === '~offline-length') { - $row['glyph'] = 'off'; - $color = '#444'; - } else { - $row['glyph'] = 'user'; - $color = '#e77'; - } - $spans['graph'] .= '
 
'; - $spans['rows'][] = $row; - $last = $row; - } - if ($first && $client['lastboot'] > $cutoff) { - // Special case: offline before - $spans['graph'] .= '
 
'; - } - if (isset($client['state_occupied'])) { - $spans['graph'] .= '
 
'; - } elseif (isset($client['state_off'])) { - $spans['graph'] .= '
 
'; - } - $t = explode('-', date('Y-n-j-G', $cutoff)); - if ($t[3] >= 8 && $t[3] <= 22) { - $start = mktime(22, 0, 0, $t[1], $t[2], $t[0]); - } else { - $start = mktime(22, 0, 0, $t[1], $t[2] - 1, $t[0]); - } - for ($i = $start; $i < $NOW; $i += 86400) { - $spans['graph'] .= '
 
'; - } - if (count($spans['rows']) > 10) { - $spans['hasrows2'] = true; - $spans['rows2'] = array_slice($spans['rows'], ceil(count($spans['rows']) / 2)); - $spans['rows'] = array_slice($spans['rows'], 0, ceil(count($spans['rows']) / 2)); - } - Render::addTemplate('statistics/machine-usage', $spans); - // Any hdds? - if (!empty($hdds['hdds'])) { - Render::addScriptBottom('chart.min'); - Render::addTemplate('statistics/machine-hdds', $hdds); - } - // Client log - $lres = Database::simpleQuery("SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog" - . " WHERE clientip = :clientip ORDER BY logid DESC LIMIT 25", array('clientip' => $client['clientip'])); - $today = date('d.m.Y'); - $yesterday = date('d.m.Y', time() - 86400); - $count = 0; - $log = array(); - while ($row = $lres->fetch(PDO::FETCH_ASSOC)) { - if (substr($row['description'], -5) === 'on :0' && strpos($row['description'], 'root logged') === false) continue; - $day = date('d.m.Y', $row['dateline']); - if ($day === $today) { - $day = Dictionary::translate('today'); - } elseif ($day === $yesterday) { - $day = Dictionary::translate('yesterday'); - } - $row['date'] = $day . date(' H:i', $row['dateline']); - $row['icon'] = $this->eventToIconName($row['logtypeid']); - $log[] = $row; - if (++$count === 10) break; - } - Render::addTemplate('statistics/syslog', array( - 'clientip' => $client['clientip'], - 'list' => $log - )); - // Notes - Render::addTemplate('statistics/machine-notes', $client); - } - - private function eventToIconName($event) - { - switch ($event) { - case 'session-open': - return 'glyphicon-log-in'; - case 'session-close': - return 'glyphicon-log-out'; - case 'partition-swap': - return 'glyphicon-info-sign'; - case 'partition-temp': - case 'smartctl-realloc': - return 'glyphicon-exclamation-sign'; - default: - return 'glyphicon-minus'; - } - } - - private function parseCpu(&$row, $data) - { - if (0 >= preg_match_all('/^(.+):\s+(\d+)$/im', $data, $out, PREG_SET_ORDER)) return; - foreach ($out as $entry) { - $row[str_replace(' ', '', $entry[1])] = $entry[2]; - } - } - - private function parseDmiDecode(&$row, $data) - { - $lines = preg_split("/[\r\n]+/", $data); - $section = false; - $ramOk = false; - $ramForm = $ramType = $ramSpeed = $ramClockSpeed = false; - foreach ($lines as $line) { - if (empty($line)) continue; - if ($line{0} !== "\t" && $line{0} !== ' ') { - $section = $line; - $ramOk = false; - if (($ramForm || $ramType) && ($ramSpeed || $ramClockSpeed)) { - if (isset($row['ramtype']) && !$ramClockSpeed) continue; - $row['ramtype'] = $ramType . ' ' . $ramForm; - if ($ramClockSpeed) $row['ramtype'] .= ', ' . $ramClockSpeed; - elseif ($ramSpeed) $row['ramtype'] .= ', ' . $ramSpeed; - $ramForm = false; - $ramType = false; - $ramClockSpeed = false; - } - continue; - } - if ($section === 'System Information' || $section === 'Base Board Information') { - if (empty($row['pcmodel']) && preg_match('/^\s*Product Name: +(\S.+?) *$/i', $line, $out)) { - $row['pcmodel'] = $out[1]; - } - if (empty($row['manufacturer']) && preg_match('/^\s*Manufacturer: +(\S.+?) *$/i', $line, $out)) { - $row['manufacturer'] = $out[1]; - } - } - else if ($section === 'Physical Memory Array') { - if (!$ramOk && preg_match('/Use: System Memory/i', $line)) { - $ramOk = true; - } - if ($ramOk && preg_match('/^\s*Number Of Devices: +(\S.+?) *$/i', $line, $out)) { - $row['ramslotcount'] = $out[1]; - } - if ($ramOk && preg_match('/^\s*Maximum Capacity: +(\S.+?)\s*$/i', $line, $out)) { - $row['maxram'] = preg_replace('/([MGT])B/', '$1iB', $out[1]); - } - } - else if ($section === 'Memory Device') { - if (preg_match('/^\s*Size:\s*(.*?)\s*$/i', $line, $out)) { - $row['extram'] = true; - if (preg_match('/(\d+)\s*(\w)i?B/i', $out[1], $out)) { - $out[2] = strtoupper($out[2]); - if ($out[2] === 'K' || ($out[2] === 'M' && $out[1] < 500)) { - $ramForm = $ramType = $ramSpeed = $ramClockSpeed = false; - continue; - } - if ($out[2] === 'M' && $out[1] >= 1024) { - $out[2] = 'G'; - $out[1] = floor(($out[1] + 100) / 1024); - } - $row['ramslot'][]['size'] = $out[1] . ' ' . strtoupper($out[2]) . 'iB'; - } else if (!isset($row['ramslot']) || (count($row['ramslot']) < 8 && (!isset($row['ramslotcount']) || $row['ramslotcount'] <= 8))) { - $row['ramslot'][]['size'] = '_____'; - } - } - if (preg_match('/^\s*Form Factor:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { - $ramForm = $out[1]; - } - if (preg_match('/^\s*Type:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { - $ramType = $out[1]; - } - if (preg_match('/^\s*Speed:\s*(\d.*?)\s*$/i', $line, $out)) { - $ramSpeed = $out[1]; - } - if (preg_match('/^\s*Configured Clock Speed:\s*(\d.*?)\s*$/i', $line, $out)) { - $ramClockSpeed = $out[1]; - } - } - } - if (empty($row['ramslotcount'])) $row['ramslotcount'] = count($row['ramslot']); - } - - private function parseHdd(&$row, $data) - { - $hdds = array(); - // Could have more than one disk - linear scan - $lines = preg_split("/[\r\n]+/", $data); - $dev = false; - $i = 0; - foreach ($lines as $line) { - if (preg_match('/^Disk (\S+):.* (\d+) bytes/i', $line, $out)) { - // disk total size and name - unset($hdd); - $unit = 0; - $hdd = array( - 'devid' => 'devid-' . ++$i, - 'dev' => $out[1], - 'size' => round($out[2] / (1024 * 1024 * 1024)), - 'used' => 0, - 'partitions' => array(), - 'json' => array(), - ); - $hdds[] = &$hdd; - } elseif (preg_match('/^Units =.*= (\d+) bytes/i', $line, $out)) { - // Unit for start and end - $unit = $out[1] / (1024 * 1024); // Convert so that multiplying by unit yields MiB - } else if (isset($hdd) && $unit !== 0 && preg_match(',^/dev/(\S+)\s+.*\s(\d+)[\+\-]?\s+(\d+)[\+\-]?\s+\d+[\+\-]?\s+([0-9a-f]+)\s+(.*)$,i', $line, $out)) { - // Some partition - $type = strtolower($out[4]); - if ($type === '5' || $type === 'f' || $type === '85') continue; - $partsize = round(($out[3] - $out[2]) * $unit); - $hdd['partitions'][] = array( - 'id' => $out[1], - 'name' => $out[1], - 'size' => round($partsize / 1024, $partsize < 1024 ? 1 : 0), - 'type' => ($type === '44' ? 'OpenSLX' : $out[5]), - ); - $hdd['json'][] = array( - 'label' => $out[1], - 'value' => $partsize, - 'color' => ($type === '44' ? '#4d4' : ($type === '82' ? '#48f' : '#e55')), - ); - $hdd['used'] += $partsize; - } - } - unset($hdd); - $i = 0; - foreach ($hdds as &$hdd) { - $hdd['used'] = round($hdd['used'] / 1024); - $free = $hdd['size'] - $hdd['used']; - if ($free > 5) { - $hdd['partitions'][] = array( - 'id' => 'free-id-' . $i, - 'name' => Dictionary::translate('unused'), - 'size' => $free, - 'type' => '-', - ); - $hdd['json'][] = array( - 'label' => 'free-id-' . $i, - 'value' => $free * 1024, - 'color' => '#aaa', - ); - ++$i; - } - $hdd['json'] = json_encode($hdd['json']); - } - unset($hdd); - $row['hdds'] = &$hdds; - } - - private function parseSmartctl(&$hdds, $data) - { - $lines = preg_split("/[\r\n]+/", $data); - $i = 0; - foreach ($lines as $line) { - if (preg_match('/^NEXTHDD=(.+)$/', $line, $out)) { - unset($dev); - foreach ($hdds as &$hdd) { - if ($hdd['dev'] === $out[1]) $dev =& $hdd; - } - continue; - } - if (!isset($dev)) continue; - if (preg_match('/^([A-Z][^:]+):\s*(.*)$/', $line, $out)) { - $dev['s_' . preg_replace('/\s|-|_/', '', $out[1])] = $out[2]; - } elseif (preg_match('/^\s*\d+\s+(\S+)\s+\S+\s+\d+\s+\d+\s+\d+\s+\S+\s+(\d+)(\s|$)/', $line, $out)) { - $dev['s_' . preg_replace('/\s|-|_/', '', $out[1])] = $out[2]; - } - } - // Format strings - foreach ($hdds as &$hdd) { - if (isset($hdd['s_PowerOnHours'])) { - $hdd['PowerOnTime'] = ''; - $val = (int)$hdd['s_PowerOnHours']; - if ($val > 8760) { - $hdd['PowerOnTime'] .= floor($val / 8760) . 'Y, '; - $val %= 8760; - } - if ($val > 720) { - $hdd['PowerOnTime'] .= floor($val / 720) . 'M, '; - $val %= 720; - } - if ($val > 24) { - $hdd['PowerOnTime'] .= floor($val / 24) . 'd, '; - $val %= 24; - } - $hdd['PowerOnTime'] .= $val . 'h'; - } - } - } - -} diff --git a/modules/statistics/config.json b/modules/statistics/config.json new file mode 100644 index 00000000..17acab76 --- /dev/null +++ b/modules/statistics/config.json @@ -0,0 +1,5 @@ +{ + "category":"status", + "enabled":"true", + "permission":"0" +} diff --git a/modules/statistics/module.inc.php b/modules/statistics/module.inc.php new file mode 100644 index 00000000..faf88521 --- /dev/null +++ b/modules/statistics/module.inc.php @@ -0,0 +1,792 @@ + $uuid, + 'text' => $text + )); + Message::addSuccess('notes-saved'); + Util::redirect('?do=Statistics&uuid=' . $uuid); + } + } + + protected function doRender() + { + Render::setTitle(Dictionary::translate('lang_titleClientStatistics')); + $uuid = Request::get('uuid', false, 'string'); + if ($uuid !== false) { + $this->showMachine($uuid); + return; + } + $filter = Request::get('filter', false, 'string'); + if ($filter !== false) { + $argument = Request::get('argument', false, 'string'); + $this->showMachineList($filter, $argument); + return; + } + Render::addScriptBottom('chart.min'); + Render::openTag('div', array('class' => 'row')); + $this->showSummary(); + $this->showMemory(); + $this->showId44(); + $this->showKvmState(); + $this->showLatestMachines(); + $this->showSystemModels(); + Render::closeTag('div'); + } + + private function capChart(&$json, $cutoff, $minSlice = 0.015) + { + $total = 0; + foreach ($json as $entry) { + $total += $entry['value']; + } + if ($total === 0) + return; + $cap = ceil($total * $cutoff); + $accounted = 0; + $id = 0; + foreach ($json as $entry) { + if (($accounted >= $cap || $entry['value'] / $total < $minSlice) && $id >= 3) break; + $id++; + $accounted += $entry['value']; + } + $json = array_slice($json, 0, $id); + if ($accounted / $total < 0.99) { + $json[] = array( + 'color' => '#eee', + 'label' => 'invalid', + 'value' => ($total - $accounted) + ); + } + } + + private function showSummary() + { + $cutoff = time() - 86400 * 30; + $online = time() - 610; + $known = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE lastseen > $cutoff"); + $on = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE lastseen > $online"); + $used = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE lastseen > $online AND logintime <> 0"); + $hdd = Database::queryFirst("SELECT Count(*) AS val FROM machine WHERE badsectors > 10 AND lastseen > $cutoff"); + if ($on['val'] != 0) { + $usedpercent = round($used['val'] / $on['val'] * 100); + } else { + $usedpercent = 0; + } + $data = array( + 'known' => $known['val'], + 'online' => $on['val'], + 'used' => $used['val'], + 'usedpercent' => $usedpercent, + 'badhdd' => $hdd['val'] + ); + // Graph + $cutoff = time() - 2*86400; + $res = Database::simpleQuery("SELECT dateline, data FROM statistic WHERE typeid = '~stats' AND dateline > $cutoff ORDER BY dateline ASC"); + $labels = array(); + $points1 = array('data' => array(), 'label' => 'Online', 'fillColor' => '#efe', 'strokeColor' => '#aea', 'pointColor' => '#7e7', 'pointStrokeColor' => '#fff', 'pointHighlightFill' => '#fff', 'pointHighlightStroke' => '#7e7'); + $points2 = array('data' => array(), 'label' => 'In use', 'fillColor' => '#fee', 'strokeColor' => '#eaa', 'pointColor' => '#e77', 'pointStrokeColor' => '#fff', 'pointHighlightFill' => '#fff', 'pointHighlightStroke' => '#e77'); + $sum = 0; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $x = explode('#', $row['data']); + if ($sum === 0) { + $labels[] = date('H:i', $row['dateline']); + } else { + $x[1] = max($x[1], array_pop($points1['data'])); + $x[2] = max($x[2], array_pop($points2['data'])); + } + $points1['data'][] = $x[1]; + $points2['data'][] = $x[2]; + $sum++; + if ($sum === 12) { + $sum = 0; + } + } + $data['json'] = json_encode(array('labels' => $labels, 'datasets' => array($points1, $points2))); + // Draw + Render::addTemplate('summary', $data); + } + + private function showSystemModels() + { + global $STATS_COLORS; + $res = Database::simpleQuery("SELECT systemmodel, Round(AVG(realcores)) AS cores, Count(*) AS `count` FROM machine" + . " GROUP BY systemmodel ORDER BY `count` DESC, systemmodel ASC"); + $lines = array(); + $json = array(); + $id = 0; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if (empty($row['systemmodel'])) continue; + settype($row['count'], 'integer'); + $row['id'] = 'systemid' . $id; + $row['urlsystemmodel'] = urlencode($row['systemmodel']); + $lines[] = $row; + $json[] = array( + 'color' => $STATS_COLORS[$id % count($STATS_COLORS)], + 'label' => 'systemid' . $id, + 'value' => $row['count'] + ); + ++$id; + } + $this->capChart($json, 0.92); + Render::addTemplate('cpumodels', array('rows' => $lines, 'json' => json_encode($json))); + } + + private function showMemory() + { + global $STATS_COLORS, $SIZE_RAM; + $res = Database::simpleQuery("SELECT mbram, Count(*) AS `count` FROM machine GROUP BY mbram"); + $lines = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $gb = ceil($row['mbram'] / 1024); + for ($i = 1; $i < count($SIZE_RAM); ++$i) { + if ($SIZE_RAM[$i] < $gb) continue; + if ($SIZE_RAM[$i] - $gb >= $gb - $SIZE_RAM[$i-1]) --$i; + $gb = $SIZE_RAM[$i]; + break; + } + if (isset($lines[$gb])) { + $lines[$gb] += $row['count']; + } else { + $lines[$gb] = $row['count']; + } + } + asort($lines); + $data = array('rows' => array()); + $json = array(); + $id = 0; + foreach (array_reverse($lines, true) as $k => $v) { + $data['rows'][] = array('gb' => $k, 'count' => $v, 'class' => $this->ramColorClass($k * 1024)); + $json[] = array( + 'color' => $STATS_COLORS[$id % count($STATS_COLORS)], + 'label' => (string)$k, + 'value' => $v + ); + ++$id; + } + $this->capChart($json, 0.92); + $data['json'] = json_encode($json); + Render::addTemplate('memory', $data); + } + + private function showKvmState() + { + $colors = array('UNKNOWN' => '#666', 'UNSUPPORTED' => '#ea5', 'DISABLED' => '#e55', 'ENABLED' => '#6d6'); + $res = Database::simpleQuery("SELECT kvmstate, Count(*) AS `count` FROM machine GROUP BY kvmstate ORDER BY `count` DESC"); + $lines = array(); + $json = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $lines[] = $row; + $json[] = array( + 'color' => isset($colors[$row['kvmstate']]) ? $colors[$row['kvmstate']] : '#000', + 'label' => $row['kvmstate'], + 'value' => $row['count'] + ); + } + Render::addTemplate('kvmstate', array('rows' => $lines, 'json' => json_encode($json))); + } + + private function showId44() + { + global $STATS_COLORS, $SIZE_ID44; + $res = Database::simpleQuery("SELECT id44mb, Count(*) AS `count` FROM machine GROUP BY id44mb"); + $lines = array(); + $total = 0; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $total += $row['count']; + $gb = ceil($row['id44mb'] / 1024); + for ($i = 1; $i < count($SIZE_ID44); ++$i) { + if ($SIZE_ID44[$i] < $gb) continue; + if ($SIZE_ID44[$i] - $gb >= $gb - $SIZE_ID44[$i-1]) --$i; + $gb = $SIZE_ID44[$i]; + break; + } + if (isset($lines[$gb])) { + $lines[$gb] += $row['count']; + } else { + $lines[$gb] = $row['count']; + } + } + asort($lines); + $data = array('rows' => array()); + $json = array(); + $id = 0; + foreach (array_reverse($lines, true) as $k => $v) { + $data['rows'][] = array('gb' => $k, 'count' => $v, 'class' => $this->hddColorClass($k)); + if ($k === 0) { + $color = '#e55'; + } else { + $color = $STATS_COLORS[$id++ % count($STATS_COLORS)]; + } + $json[] = array( + 'color' => $color, + 'label' => (string)$k, + 'value' => $v + ); + } + $this->capChart($json, 0.95); + $data['json'] = json_encode($json); + Render::addTemplate('id44', $data); + } + + private function showLatestMachines() + { + $data = array('cutoff' => ceil(time() / 3600) * 3600 - 86400 * 7); + $res = Database::simpleQuery("SELECT machineuuid, clientip, hostname, firstseen, mbram, kvmstate, id44mb FROM machine" + . " WHERE firstseen > :cutoff ORDER BY firstseen DESC LIMIT 32", $data); + $rows = array(); + $count = 0; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if (empty($row['hostname'])) { + $row['hostname'] = $row['clientip']; + } + $row['firstseen'] = date('d.m. H:i', $row['firstseen']); + $row['gbram'] = round(round($row['mbram'] / 500) / 2, 1); // Trial and error until we got "expected" rounding.. + $row['gbtmp'] = round($row['id44mb'] / 1024); + $row['ramclass'] = $this->ramColorClass($row['mbram']); + $row['kvmclass'] = $this->kvmColorClass($row['kvmstate']); + $row['hddclass'] = $this->hddColorClass($row['gbtmp']); + $row['kvmicon'] = $row['kvmstate'] === 'ENABLED' ? '✓' : '✗'; + if (++$count > 5) { + $row['style'] = 'display:none'; + } + $rows[] = $row; + } + Render::addTemplate('newclients', array('rows' => $rows, 'openbutton' => $count > 5)); + } + + private function showMachineList($filter, $argument) + { + global $SIZE_RAM, $SIZE_ID44; + $join = ''; + $filters = array('cpumodel', 'realcores', 'kvmstate', 'clientip', 'macaddr', 'machineuuid', 'systemmodel'); + if (in_array($filter, $filters)) { + // Simple filters mapping into db + $where = " $filter = :argument"; + $args = array('argument' => $argument); + } elseif ($filter === 'gbram') { + // Memory by rounded GB + $lower = floor($this->findBestValue($SIZE_RAM, $argument, false) * 1024 - 100); + $upper = ceil($this->findBestValue($SIZE_RAM, $argument, true) * 1024 + 100); + $where = " mbram BETWEEN $lower AND $upper"; + $args = array(); + } elseif ($filter === 'hddgb') { + // HDD by rounded GB + $lower = floor($this->findBestValue($SIZE_ID44, $argument, false) * 1024 - 100); + $upper = ceil($this->findBestValue($SIZE_ID44, $argument, true) * 1024 + 100); + $where = " id44mb BETWEEN $lower AND $upper"; + $args = array(); + } elseif ($filter === 'subnet') { + $argument = preg_replace('/[^0-9\.:]/', '', $argument); + $where = " clientip LIKE '$argument%'"; + $args = array(); + } elseif ($filter === 'badsectors') { + $where = " badsectors >= :argument "; + $args = array('argument' => $argument); + } elseif ($filter === 'state') { + if ( $argument === 'on') { + $where = " lastseen + 600 > UNIX_TIMESTAMP() "; + } elseif ($argument === 'off') { + $where = " lastseen + 600 < UNIX_TIMESTAMP() "; + } elseif ($argument === 'idle') { + $where = " lastseen + 600 > UNIX_TIMESTAMP() AND logintime = 0 "; + } elseif ($argument === 'occupied') { + $where = " lastseen + 600 > UNIX_TIMESTAMP() AND logintime <> 0 "; + } else { + Message::addError('invalid-filter'); + return; + } + } elseif ($filter === 'location') { + $where = "subnet.locationid = :lid OR machine.locationid = :lid"; + $join = " INNER JOIN subnet ON (INET_ATON(clientip) BETWEEN startaddr AND endaddr) "; + $args = array('lid' => (int)$argument); + } else { + Message::addError('invalid-filter'); + return; + } + $res = Database::simpleQuery("SELECT machineuuid, macaddr, clientip, firstseen, lastseen," + . " logintime, lastboot, realcores, mbram, kvmstate, cpumodel, id44mb, hostname, notes IS NOT NULL AS hasnotes, badsectors FROM machine" + . " $join WHERE $where ORDER BY lastseen DESC, clientip ASC", $args); + $rows = array(); + $NOW = time(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($NOW - $row['lastseen'] > 610) { + $row['state_off'] = true; + } elseif ($row['logintime'] == 0) { + $row['state_idle'] = true; + } else { + $row['state_occupied'] = true; + } + //$row['firstseen'] = date('d.m.Y H:i', $row['firstseen']); + $row['lastseen'] = date('d.m. H:i', $row['lastseen']); + //$row['lastboot'] = date('d.m. H:i', $row['lastboot']); + $row['gbram'] = round(round($row['mbram'] / 500) / 2, 1); // Trial and error until we got "expected" rounding.. + $row['gbtmp'] = round($row['id44mb'] / 1024); + $octets = explode('.', $row['clientip']); + if (count($octets) === 4) { + $row['subnet'] = "$octets[0].$octets[1].$octets[2]."; + $row['lastoctet'] = $octets[3]; + } + $row['ramclass'] = $this->ramColorClass($row['mbram']); + $row['kvmclass'] = $this->kvmColorClass($row['kvmstate']); + $row['hddclass'] = $this->hddColorClass($row['gbtmp']); + if (empty($row['hostname'])) $row['hostname'] = $row['clientip']; + $rows[] = $row; + } + Render::addTemplate('clientlist', array('rows' => $rows, 'filter' => $filter, 'argument' => $argument)); + } + + private function ramColorClass($mb) + { + if ($mb < 1500) + return 'danger'; + if ($mb < 2500) + return 'warning'; + return ''; + } + + private function kvmColorClass($state) + { + if ($state === 'DISABLED') + return 'danger'; + if ($state === 'UNKNOWN' || $state === 'UNSUPPORTED') + return 'warning'; + return ''; + } + + private function hddColorClass($gb) + { + if ($gb < 7) + return 'danger'; + if ($gb < 25) + return 'warning'; + return ''; + } + + private function findBestValue($array, $value, $up) + { + $best = 0; + for ($i = 0; $i < count($array); ++$i) { + if (abs($array[$i] - $value) < abs($array[$best] - $value)) { + $best = $i; + } + } + if (!$up && $best === 0) { + return $array[0]; + } + if ($up && $best + 1 === count($array)) { + return $array[$best]; + } + if ($up) { + return ($array[$best] + $array[$best + 1]) / 2; + } + return ($array[$best] + $array[$best - 1]) / 2; + } + + private function fillSessionInfo(&$row) + { + $res = Database::simpleQuery("SELECT dateline, username, data FROM statistic" + . " WHERE clientip = :ip AND typeid = '.vmchooser-session-name'" + . " AND dateline BETWEEN :start AND :end", array( + 'ip' => $row['clientip'], + 'start' => $row['logintime'] - 60, + 'end' => $row['logintime'] + 300 + )); + $session = false; + while ($r = $res->fetch(PDO::FETCH_ASSOC)) { + if ($session === false || abs($session['dateline'] - $row['logintime']) > abs($r['dateline'] - $row['logintime'])) { + $session = $r; + } + } + if ($session !== false) { + $row['session'] = $session['data']; + $row['username'] = $session['username']; + } + } + + private function showMachine($uuid) + { + $client = Database::queryFirst("SELECT machineuuid, macaddr, clientip, firstseen, lastseen, logintime, lastboot," + . " mbram, kvmstate, cpumodel, id44mb, data, hostname, notes FROM machine WHERE machineuuid = :uuid", + array('uuid' => $uuid)); + // Mangle fields + $NOW = time(); + if ($NOW - $client['lastseen'] > 610) { + $client['state_off'] = true; + } elseif ($client['logintime'] == 0) { + $client['state_idle'] = true; + } else { + $client['state_occupied'] = true; + $this->fillSessionInfo($client); + } + $client['firstseen_s'] = date('d.m.Y H:i', $client['firstseen']); + $client['lastseen_s'] = date('d.m.Y H:i', $client['lastseen']); + $uptime = $NOW - $client['lastboot']; + $client['lastboot_s'] = date('d.m.Y H:i', $client['lastboot']) . ' (Up ' . floor($uptime / 86400) . 'd ' . gmdate('H:i', $uptime) . ')'; + $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']); + $client['gbram'] = round(round($client['mbram'] / 500) / 2, 1); + $client['gbtmp'] = round($client['id44mb'] / 1024); + $client['ramclass'] = $this->ramColorClass($client['mbram']); + $client['kvmclass'] = $this->kvmColorClass($client['kvmstate']); + $client['hddclass'] = $this->hddColorClass($client['gbtmp']); + // Parse the giant blob of data + $hdds = array(); + if (preg_match_all('/##### ([^#]+) #+$(.*?)^#####/ims', $client['data'] . '########', $out, PREG_SET_ORDER)) { + foreach ($out as $section) { + if ($section[1] === 'CPU') { + $this->parseCpu($client, $section[2]); + } + if ($section[1] === 'dmidecode') { + $this->parseDmiDecode($client, $section[2]); + } + if ($section[1] === 'Partition tables') { + $this->parseHdd($hdds, $section[2]); + } + if (isset($hdds['hdds']) && $section[1] === 'smartctl') { + // This currently required that the partition table section comes first... + $this->parseSmartctl($hdds['hdds'], $section[2]); + } + } + } + unset($client['data']); + // Throw output at user + Render::addTemplate('machine-main', $client); + // Sessions + $NOW = time(); + $cutoff = $NOW - 86400 * 7; + //if ($cutoff < $client['firstseen']) $cutoff = $client['firstseen']; + $scale = 100 / ($NOW - $cutoff); + $res = Database::simpleQuery("SELECT dateline, typeid, data FROM statistic" + . " WHERE dateline > :cutoff AND typeid IN ('~session-length', '~offline-length') AND machineuuid = :uuid ORDER BY dateline ASC", array( + 'cutoff' => $cutoff - 86400 * 14, + 'uuid' => $uuid + )); + $spans['rows'] = array(); + $spans['graph'] = ''; + $last = false; + $first = true; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($first && $row['dateline'] > $cutoff && $client['lastboot'] > $cutoff) { + // Special case: offline before + $spans['graph'] .= '
 
'; + } + $first = false; + if ($row['dateline'] + $row['data'] < $cutoff || $row['data'] > 864000) continue; + if ($last !== false && abs($last['dateline'] - $row['dateline']) < 30 + && abs($last['data'] - $row['data']) < 30) continue; + if ($last !== false && $last['dateline'] + $last['data'] > $row['dateline']) { + $point = $last['dateline'] + $last['data']; + $row['data'] -= ($point - $row['dateline']); + $row['dateline'] = $point; + } + if ($row['dateline'] < $cutoff) { + $row['data'] -= ($cutoff - $row['dateline']); + $row['dateline'] = $cutoff; + } + $row['from'] = date('d.m. H:i', $row['dateline']); + $row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']); + if ($row['typeid'] === '~offline-length') { + $row['glyph'] = 'off'; + $color = '#444'; + } else { + $row['glyph'] = 'user'; + $color = '#e77'; + } + $spans['graph'] .= '
 
'; + $spans['rows'][] = $row; + $last = $row; + } + if ($first && $client['lastboot'] > $cutoff) { + // Special case: offline before + $spans['graph'] .= '
 
'; + } + if (isset($client['state_occupied'])) { + $spans['graph'] .= '
 
'; + } elseif (isset($client['state_off'])) { + $spans['graph'] .= '
 
'; + } + $t = explode('-', date('Y-n-j-G', $cutoff)); + if ($t[3] >= 8 && $t[3] <= 22) { + $start = mktime(22, 0, 0, $t[1], $t[2], $t[0]); + } else { + $start = mktime(22, 0, 0, $t[1], $t[2] - 1, $t[0]); + } + for ($i = $start; $i < $NOW; $i += 86400) { + $spans['graph'] .= '
 
'; + } + if (count($spans['rows']) > 10) { + $spans['hasrows2'] = true; + $spans['rows2'] = array_slice($spans['rows'], ceil(count($spans['rows']) / 2)); + $spans['rows'] = array_slice($spans['rows'], 0, ceil(count($spans['rows']) / 2)); + } + Render::addTemplate('machine-usage', $spans); + // Any hdds? + if (!empty($hdds['hdds'])) { + Render::addScriptBottom('chart.min'); + Render::addTemplate('machine-hdds', $hdds); + } + // Client log + $lres = Database::simpleQuery("SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog" + . " WHERE clientip = :clientip ORDER BY logid DESC LIMIT 25", array('clientip' => $client['clientip'])); + $today = date('d.m.Y'); + $yesterday = date('d.m.Y', time() - 86400); + $count = 0; + $log = array(); + while ($row = $lres->fetch(PDO::FETCH_ASSOC)) { + if (substr($row['description'], -5) === 'on :0' && strpos($row['description'], 'root logged') === false) continue; + $day = date('d.m.Y', $row['dateline']); + if ($day === $today) { + $day = Dictionary::translate('today'); + } elseif ($day === $yesterday) { + $day = Dictionary::translate('yesterday'); + } + $row['date'] = $day . date(' H:i', $row['dateline']); + $row['icon'] = $this->eventToIconName($row['logtypeid']); + $log[] = $row; + if (++$count === 10) break; + } + Render::addTemplate('syslog', array( + 'clientip' => $client['clientip'], + 'list' => $log + )); + // Notes + Render::addTemplate('machine-notes', $client); + } + + private function eventToIconName($event) + { + switch ($event) { + case 'session-open': + return 'glyphicon-log-in'; + case 'session-close': + return 'glyphicon-log-out'; + case 'partition-swap': + return 'glyphicon-info-sign'; + case 'partition-temp': + case 'smartctl-realloc': + return 'glyphicon-exclamation-sign'; + default: + return 'glyphicon-minus'; + } + } + + private function parseCpu(&$row, $data) + { + if (0 >= preg_match_all('/^(.+):\s+(\d+)$/im', $data, $out, PREG_SET_ORDER)) return; + foreach ($out as $entry) { + $row[str_replace(' ', '', $entry[1])] = $entry[2]; + } + } + + private function parseDmiDecode(&$row, $data) + { + $lines = preg_split("/[\r\n]+/", $data); + $section = false; + $ramOk = false; + $ramForm = $ramType = $ramSpeed = $ramClockSpeed = false; + foreach ($lines as $line) { + if (empty($line)) continue; + if ($line{0} !== "\t" && $line{0} !== ' ') { + $section = $line; + $ramOk = false; + if (($ramForm || $ramType) && ($ramSpeed || $ramClockSpeed)) { + if (isset($row['ramtype']) && !$ramClockSpeed) continue; + $row['ramtype'] = $ramType . ' ' . $ramForm; + if ($ramClockSpeed) $row['ramtype'] .= ', ' . $ramClockSpeed; + elseif ($ramSpeed) $row['ramtype'] .= ', ' . $ramSpeed; + $ramForm = false; + $ramType = false; + $ramClockSpeed = false; + } + continue; + } + if ($section === 'System Information' || $section === 'Base Board Information') { + if (empty($row['pcmodel']) && preg_match('/^\s*Product Name: +(\S.+?) *$/i', $line, $out)) { + $row['pcmodel'] = $out[1]; + } + if (empty($row['manufacturer']) && preg_match('/^\s*Manufacturer: +(\S.+?) *$/i', $line, $out)) { + $row['manufacturer'] = $out[1]; + } + } + else if ($section === 'Physical Memory Array') { + if (!$ramOk && preg_match('/Use: System Memory/i', $line)) { + $ramOk = true; + } + if ($ramOk && preg_match('/^\s*Number Of Devices: +(\S.+?) *$/i', $line, $out)) { + $row['ramslotcount'] = $out[1]; + } + if ($ramOk && preg_match('/^\s*Maximum Capacity: +(\S.+?)\s*$/i', $line, $out)) { + $row['maxram'] = preg_replace('/([MGT])B/', '$1iB', $out[1]); + } + } + else if ($section === 'Memory Device') { + if (preg_match('/^\s*Size:\s*(.*?)\s*$/i', $line, $out)) { + $row['extram'] = true; + if (preg_match('/(\d+)\s*(\w)i?B/i', $out[1], $out)) { + $out[2] = strtoupper($out[2]); + if ($out[2] === 'K' || ($out[2] === 'M' && $out[1] < 500)) { + $ramForm = $ramType = $ramSpeed = $ramClockSpeed = false; + continue; + } + if ($out[2] === 'M' && $out[1] >= 1024) { + $out[2] = 'G'; + $out[1] = floor(($out[1] + 100) / 1024); + } + $row['ramslot'][]['size'] = $out[1] . ' ' . strtoupper($out[2]) . 'iB'; + } else if (!isset($row['ramslot']) || (count($row['ramslot']) < 8 && (!isset($row['ramslotcount']) || $row['ramslotcount'] <= 8))) { + $row['ramslot'][]['size'] = '_____'; + } + } + if (preg_match('/^\s*Form Factor:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { + $ramForm = $out[1]; + } + if (preg_match('/^\s*Type:\s*(.*?)\s*$/i', $line, $out) && $out[1] !== 'Unknown') { + $ramType = $out[1]; + } + if (preg_match('/^\s*Speed:\s*(\d.*?)\s*$/i', $line, $out)) { + $ramSpeed = $out[1]; + } + if (preg_match('/^\s*Configured Clock Speed:\s*(\d.*?)\s*$/i', $line, $out)) { + $ramClockSpeed = $out[1]; + } + } + } + if (empty($row['ramslotcount'])) $row['ramslotcount'] = count($row['ramslot']); + } + + private function parseHdd(&$row, $data) + { + $hdds = array(); + // Could have more than one disk - linear scan + $lines = preg_split("/[\r\n]+/", $data); + $dev = false; + $i = 0; + foreach ($lines as $line) { + if (preg_match('/^Disk (\S+):.* (\d+) bytes/i', $line, $out)) { + // disk total size and name + unset($hdd); + $unit = 0; + $hdd = array( + 'devid' => 'devid-' . ++$i, + 'dev' => $out[1], + 'size' => round($out[2] / (1024 * 1024 * 1024)), + 'used' => 0, + 'partitions' => array(), + 'json' => array(), + ); + $hdds[] = &$hdd; + } elseif (preg_match('/^Units =.*= (\d+) bytes/i', $line, $out)) { + // Unit for start and end + $unit = $out[1] / (1024 * 1024); // Convert so that multiplying by unit yields MiB + } else if (isset($hdd) && $unit !== 0 && preg_match(',^/dev/(\S+)\s+.*\s(\d+)[\+\-]?\s+(\d+)[\+\-]?\s+\d+[\+\-]?\s+([0-9a-f]+)\s+(.*)$,i', $line, $out)) { + // Some partition + $type = strtolower($out[4]); + if ($type === '5' || $type === 'f' || $type === '85') continue; + $partsize = round(($out[3] - $out[2]) * $unit); + $hdd['partitions'][] = array( + 'id' => $out[1], + 'name' => $out[1], + 'size' => round($partsize / 1024, $partsize < 1024 ? 1 : 0), + 'type' => ($type === '44' ? 'OpenSLX' : $out[5]), + ); + $hdd['json'][] = array( + 'label' => $out[1], + 'value' => $partsize, + 'color' => ($type === '44' ? '#4d4' : ($type === '82' ? '#48f' : '#e55')), + ); + $hdd['used'] += $partsize; + } + } + unset($hdd); + $i = 0; + foreach ($hdds as &$hdd) { + $hdd['used'] = round($hdd['used'] / 1024); + $free = $hdd['size'] - $hdd['used']; + if ($free > 5) { + $hdd['partitions'][] = array( + 'id' => 'free-id-' . $i, + 'name' => Dictionary::translate('unused'), + 'size' => $free, + 'type' => '-', + ); + $hdd['json'][] = array( + 'label' => 'free-id-' . $i, + 'value' => $free * 1024, + 'color' => '#aaa', + ); + ++$i; + } + $hdd['json'] = json_encode($hdd['json']); + } + unset($hdd); + $row['hdds'] = &$hdds; + } + + private function parseSmartctl(&$hdds, $data) + { + $lines = preg_split("/[\r\n]+/", $data); + $i = 0; + foreach ($lines as $line) { + if (preg_match('/^NEXTHDD=(.+)$/', $line, $out)) { + unset($dev); + foreach ($hdds as &$hdd) { + if ($hdd['dev'] === $out[1]) $dev =& $hdd; + } + continue; + } + if (!isset($dev)) continue; + if (preg_match('/^([A-Z][^:]+):\s*(.*)$/', $line, $out)) { + $dev['s_' . preg_replace('/\s|-|_/', '', $out[1])] = $out[2]; + } elseif (preg_match('/^\s*\d+\s+(\S+)\s+\S+\s+\d+\s+\d+\s+\d+\s+\S+\s+(\d+)(\s|$)/', $line, $out)) { + $dev['s_' . preg_replace('/\s|-|_/', '', $out[1])] = $out[2]; + } + } + // Format strings + foreach ($hdds as &$hdd) { + if (isset($hdd['s_PowerOnHours'])) { + $hdd['PowerOnTime'] = ''; + $val = (int)$hdd['s_PowerOnHours']; + if ($val > 8760) { + $hdd['PowerOnTime'] .= floor($val / 8760) . 'Y, '; + $val %= 8760; + } + if ($val > 720) { + $hdd['PowerOnTime'] .= floor($val / 720) . 'M, '; + $val %= 720; + } + if ($val > 24) { + $hdd['PowerOnTime'] .= floor($val / 24) . 'd, '; + $val %= 24; + } + $hdd['PowerOnTime'] .= $val . 'h'; + } + } + } + +} diff --git a/modules/statistics/templates/clientlist.html b/modules/statistics/templates/clientlist.html new file mode 100644 index 00000000..8e8565fe --- /dev/null +++ b/modules/statistics/templates/clientlist.html @@ -0,0 +1,45 @@ +

{{lang_clientList}}

+
{{filter}} ~= {{argument}}
+
+ + + + + + + + + + + + {{#rows}} + + + + + + + + + + {{/rows}} +
{{lang_machine}}{{lang_address}}{{lang_lastSeen}}{{lang_kvmSupport}}{{lang_gbRam}}{{lang_tmpGb}}{{lang_cpuModel}}
+ {{#hasnotes}}{{/hasnotes}} + {{#state_off}} + + {{/state_off}} + {{#state_idle}} + + {{/state_idle}} + {{#state_occupied}} + + {{/state_occupied}} + {{hostname}} +
{{machineuuid}}
+
{{subnet}}{{lastoctet}}
{{macaddr}}
{{lastseen}}{{kvmstate}}{{gbram}} GiB + {{gbtmp}} GiB + {{#badsectors}}
+ + {{badsectors}} +
{{/badsectors}} +
{{lang_realCores}}: {{realcores}}
{{cpumodel}}
diff --git a/modules/statistics/templates/cpumodels.html b/modules/statistics/templates/cpumodels.html new file mode 100644 index 00000000..2f24cd92 --- /dev/null +++ b/modules/statistics/templates/cpumodels.html @@ -0,0 +1,51 @@ +
+
+
+ {{lang_modelStats}} +
+
+
+
+ + + + + + + {{#rows}} + + + + + + {{/rows}} +
{{lang_modelName}}{{lang_cpuCores}}{{lang_modelCount}}
+ {{systemmodel}} + {{cores}}{{count}}
+
+
+ + +
+
+
+
+
diff --git a/modules/statistics/templates/id44.html b/modules/statistics/templates/id44.html new file mode 100644 index 00000000..730839b1 --- /dev/null +++ b/modules/statistics/templates/id44.html @@ -0,0 +1,48 @@ +
+
+
+ {{lang_tempPartStats}} +
+
+
+
+ + + + + + {{#rows}} + + + + + {{/rows}} +
{{lang_partitionSize}}{{lang_machineCount}}
{{gb}} GiB{{count}}
+
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/modules/statistics/templates/kvmstate.html b/modules/statistics/templates/kvmstate.html new file mode 100644 index 00000000..107a34f7 --- /dev/null +++ b/modules/statistics/templates/kvmstate.html @@ -0,0 +1,47 @@ +
+
+
+ {{lang_kvmStats}} +
+
+
+
+ + + + + + {{#rows}} + + + + + {{/rows}} +
{{lang_kvmState}}{{lang_machineCount}}
{{kvmstate}}{{count}}
+
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/modules/statistics/templates/machine-hdds.html b/modules/statistics/templates/machine-hdds.html new file mode 100644 index 00000000..fd6cf1be --- /dev/null +++ b/modules/statistics/templates/machine-hdds.html @@ -0,0 +1,67 @@ +

{{lang_hdds}}

+
+ {{#hdds}} +
+
+
+ {{s_ModelFamily}} {{dev}} +
+
+ {{#s_DeviceModel}} +
{{lang_modelNo}}: {{s_DeviceModel}}, {{lang_serialNo}}: {{s_SerialNumber}}
+ {{/s_DeviceModel}} + {{#s_ReallocatedSectorCt}} +
{{lang_reallocatedSectors}}: {{s_ReallocatedSectorCt}}
+ {{/s_ReallocatedSectorCt}} + {{#s_CurrentPendingSector}} +
{{lang_pendingSectors}}: {{s_CurrentPendingSector}}
+ {{/s_CurrentPendingSector}} + {{#s_PowerOnHours}} +
{{lang_powerOnTime}}: {{s_PowerOnHours}} {{lang_hours}} ({{PowerOnTime}})
+ {{/s_PowerOnHours}} +
+
+ + + + + + + {{#partitions}} + + + + + + {{/partitions}} +
{{lang_partName}}{{lang_partSize}}{{lang_partType}}
{{name}}{{size}} GiB{{type}}
+
{{lang_total}}: {{size}} GiB
+
+
+ + +
+
+
+
+
+ {{/hdds}} +
\ No newline at end of file diff --git a/modules/statistics/templates/machine-main.html b/modules/statistics/templates/machine-main.html new file mode 100644 index 00000000..8071416a --- /dev/null +++ b/modules/statistics/templates/machine-main.html @@ -0,0 +1,124 @@ +

+ {{hostname}} {{#hostname}}–{{/hostname}} {{clientip}} + {{#notes}}{{/notes}} +

+ +
+
+
+
+ {{lang_machineSummary}} +
+
+ + + + + + + + + + + + + + {{#hostname}} + + + + + {{/hostname}} + + + + + + + + + + + + + + + + +
{{lang_uuid}}{{machineuuid}}
{{lang_macAddr}}{{macaddr}}
{{lang_ip}}{{clientip}}
{{lang_hostname}}{{hostname}}
{{lang_firstSeen}}{{firstseen_s}}
{{lang_lastBoot}}{{lastboot_s}}
{{lang_lastSeen}}{{lastseen_s}}
{{lang_usageState}} + {{#state_off}} + {{lang_machineOff}} + {{/state_off}} + {{#state_idle}} + {{lang_machineIdle}} + {{/state_idle}} + {{#state_occupied}} + {{#username}} + {{lang_machineOccupiedBy}} {{username}} + {{/username}} + {{^username}} + {{lang_machineOccupied}} + {{/username}} +
{{logintime_s}}
+ {{/state_occupied}} + {{#session}} +
{{session}}
+ {{/session}} +
+
+
+
+
+
+
+ {{lang_hardwareSummary}} +
+
+ + + + + + + + + + + + + + {{#extram}} + + + + + {{/extram}} + + + + + + + + +
{{lang_cpuModel}} + {{cpumodel}} + {{#Sockets}} +
+ {{lang_sockets}}: {{Sockets}}, {{lang_cores}}: {{Realcores}}, {{lang_virtualCores}}: {{Virtualcores}} +
+ {{/Sockets}} +
{{lang_model}}{{pcmodel}} ({{manufacturer}})
{{lang_ram}} + {{gbram}} GiB + {{#maxram}}({{lang_maximumAbbrev}} {{maxram}}){{/maxram}} + {{ramtype}} +
{{lang_ramSlots}} + {{ramslotcount}}: + {{#ramslot}} + [ {{size}} ] + {{/ramslot}} +
{{lang_tempPart}}{{gbtmp}} GiB
{{lang_64bitSupport}}{{kvmstate}}
+
+
+
+
diff --git a/modules/statistics/templates/machine-notes.html b/modules/statistics/templates/machine-notes.html new file mode 100644 index 00000000..c4f97543 --- /dev/null +++ b/modules/statistics/templates/machine-notes.html @@ -0,0 +1,17 @@ + +

{{lang_notes}}

+
+
+
+
+
+ + + + + +
+
+
+
+
\ No newline at end of file diff --git a/modules/statistics/templates/machine-usage.html b/modules/statistics/templates/machine-usage.html new file mode 100644 index 00000000..ffaa747b --- /dev/null +++ b/modules/statistics/templates/machine-usage.html @@ -0,0 +1,51 @@ +
+
+
+
+ {{lang_usageDetails}} +
+
+
+
+ + + + + + + {{#rows}} + + + + + + {{/rows}} +
TypeWhenLength
{{from}}{{duration}}
+
+
+ + {{#hasrows2}} + + + + + + {{/hasrows2}} + {{#rows2}} + + + + + + {{/rows2}} +
TypeWhenLength
{{from}}{{duration}}
+
+
+
 {{{graph}}}
+
+ {{lang_timebarDesc}} +
+
+
+
+
diff --git a/modules/statistics/templates/memory.html b/modules/statistics/templates/memory.html new file mode 100644 index 00000000..f4d2ad24 --- /dev/null +++ b/modules/statistics/templates/memory.html @@ -0,0 +1,47 @@ +
+
+
+ {{lang_memoryStats}} +
+
+
+
+ + + + + + {{#rows}} + + + + + {{/rows}} +
{{lang_ramSize}}{{lang_machineCount}}
{{gb}} GiB{{count}}
+
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/modules/statistics/templates/newclients.html b/modules/statistics/templates/newclients.html new file mode 100644 index 00000000..0d9c74df --- /dev/null +++ b/modules/statistics/templates/newclients.html @@ -0,0 +1,44 @@ +
+
+
+ {{lang_newMachines}} +
+
+ + + + + + + + + {{#rows}} + + + + + + + + {{/rows}} + {{#openbutton}} + + + + {{/openbutton}} +
{{lang_machine}}64BitRAMHDD
{{hostname}}{{firstseen}}{{kvmicon}}{{gbram}} GiB{{gbtmp}} GiB
+ + + + + + +
+
+
+
\ No newline at end of file diff --git a/modules/statistics/templates/summary.html b/modules/statistics/templates/summary.html new file mode 100644 index 00000000..5f16fd89 --- /dev/null +++ b/modules/statistics/templates/summary.html @@ -0,0 +1,33 @@ +
+
+
+
+ {{lang_knownMachines}}: {{known}}  + {{lang_onlineMachines}}: {{online}}  + {{lang_inUseMachines}}: {{used}} ({{usedpercent}}%) +
+ {{#badhdd}} + + {{/badhdd}} +
+
+
+ + +
+
+ diff --git a/modules/statistics/templates/syslog.html b/modules/statistics/templates/syslog.html new file mode 100644 index 00000000..c82cb8ac --- /dev/null +++ b/modules/statistics/templates/syslog.html @@ -0,0 +1,43 @@ +

{{lang_logHeadline}}

+ + + + + + + + + {{#list}} + + + + + + + {{/list}} + +
{{lang_when}}{{lang_event}}{{lang_details}}
{{date}}{{description}}{{#extra}} + » + + {{/extra}}
+ +
+ + + + diff --git a/modules/support/config.json b/modules/support/config.json new file mode 100644 index 00000000..4e7fa5fb --- /dev/null +++ b/modules/support/config.json @@ -0,0 +1,4 @@ +{ + "category":"content", + "enabled":"true" +} diff --git a/modules/support/module.inc.php b/modules/support/module.inc.php new file mode 100644 index 00000000..d4012c1a --- /dev/null +++ b/modules/support/module.inc.php @@ -0,0 +1,77 @@ +SMTPDebug = 3; // Enable verbose debug output + $mail->isSMTP(); // Set mailer to use SMTP + $mail->Host = 'mx.c3sl.ufpr.br'; // Specify main and backup SMTP servers + $mail->SMTPAuth = true; // Enable SMTP authentication + $mail->Username = 'xxx00@inf.ufpr.br'; // SMTP username + $mail->Password = ''; // SMTP password + // $mail->SMTPSecure = 'false'; // Enable TLS encryption, `ssl` also accepted + $mail->Port = 25; // TCP port to connect to + + $mail->From = 'xxx00@inf.ufpr.br'; + $mail->FromName = 'Someone'; + $mail->addAddress('receiver@email.com', 'Another One'); // Add a recipient + // $mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments + // $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name + $mail->isHTML(true); // Set email format to HTML + $mail->Subject = 'Here is the subject'; + $mail->Body = 'This is the HTML message body in bold!'; + $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; + + if(!$mail->send()) { + echo 'Message could not be sent.'; + echo 'Mailer Error: ' . $mail->ErrorInfo; + } else { + echo 'Message has been sent'; + } + */ +// $uploaddir = '/var/www/uploads/'; +// $uploadfile = $uploaddir . basename($_FILES['inp_file']['name']); +// if(move_uploaded_file($_FILES['inp_file']['tmp_name'], $uploadfile)) +// Message::addSuccess('news-save-success'); +// else +// Message::addError('news-empty'); +// mail($to,$_POST[assuntoEmail],$_POST[conteudoEmail],"-r".$from); +// mail($to,$assunto,$content,$headers); + + + } + + + + 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'); +// Render::addTemplate('page-support', array( +// 'token' => Session:get('token')); + } + + +} diff --git a/modules/support/templates/go-pear.phar b/modules/support/templates/go-pear.phar new file mode 100644 index 00000000..9038c747 --- /dev/null +++ b/modules/support/templates/go-pear.phar @@ -0,0 +1,99492 @@ + + * @author Greg Beaver + * @link http://www.synapticmedia.net Synaptic Media + * @version Id: Archive.php,v 1.52 2007/09/01 20:28:14 cellog Exp $ + * @package PHP_Archive + * @category PHP + */ + +class PHP_Archive +{ + const GZ = 0x00001000; + const BZ2 = 0x00002000; + const SIG = 0x00010000; + const SHA1 = 0x0002; + const MD5 = 0x0001; + /** + * Whether this archive is compressed with zlib + * + * @var bool + */ + private $_compressed; + /** + * @var string Real path to the .phar archive + */ + private $_archiveName = null; + /** + * Current file name in the phar + * @var string + */ + protected $currentFilename = null; + /** + * Length of current file in the phar + * @var string + */ + protected $internalFileLength = null; + /** + * Current file statistics (size, creation date, etc.) + * @var string + */ + protected $currentStat = null; + /** + * @var resource|null Pointer to open .phar + */ + protected $fp = null; + /** + * @var int Current Position of the pointer + */ + protected $position = 0; + + /** + * Map actual realpath of phars to meta-data about the phar + * + * Data is indexed by the alias that is used by internal files. In other + * words, if a file is included via: + * + * require_once 'phar://PEAR.phar/PEAR/Installer.php'; + * + * then the alias is "PEAR.phar" + * + * Information stored is a boolean indicating whether this .phar is compressed + * with zlib, another for bzip2, phar-specific meta-data, and + * the precise offset of internal files + * within the .phar, used with the {@link $_manifest} to load actual file contents + * @var array + */ + private static $_pharMapping = array(); + /** + * Map real file paths to alias used + * + * @var array + */ + private static $_pharFiles = array(); + /** + * File listing for the .phar + * + * The manifest is indexed per phar. + * + * Files within the .phar are indexed by their relative path within the + * .phar. Each file has this information in its internal array + * + * - 0 = uncompressed file size + * - 1 = timestamp of when file was added to phar + * - 2 = offset of file within phar relative to internal file's start + * - 3 = compressed file size (actual size in the phar) + * @var array + */ + private static $_manifest = array(); + /** + * Absolute offset of internal files within the .phar, indexed by absolute + * path to the .phar + * + * @var array + */ + private static $_fileStart = array(); + /** + * file name of the phar + * + * @var string + */ + private $_basename; + + + /** + * Default MIME types used for the web front controller + * + * @var array + */ + public static $defaultmimes = array( + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'arc' => 'application/octet-stream', + 'arj' => 'application/octet-stream', + 'art' => 'image/x-jg', + 'asf' => 'video/x-ms-asf', + 'asx' => 'video/x-ms-asf', + 'avi' => 'video/avi', + 'bin' => 'application/octet-stream', + 'bm' => 'image/bmp', + 'bmp' => 'image/bmp', + 'bz2' => 'application/x-bzip2', + 'css' => 'text/css', + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'dv' => 'video/x-dv', + 'dvi' => 'application/x-dvi', + 'eps' => 'application/postscript', + 'exe' => 'application/octet-stream', + 'gif' => 'image/gif', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'htm' => 'text/html', + 'html' => 'text/html', + 'ico' => 'image/x-icon', + 'jpe' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'js' => 'application/x-javascript', + 'log' => 'text/plain', + 'mid' => 'audio/x-midi', + 'mov' => 'video/quicktime', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg3', + 'mpg' => 'audio/mpeg', + 'pdf' => 'aplication/pdf', + 'png' => 'image/png', + 'rtf' => 'application/rtf', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'txt' => 'text/plain', + 'xml' => 'text/xml', + ); + + public static $defaultphp = array( + 'php' => true + ); + + public static $defaultphps = array( + 'phps' => true + ); + + public static $deny = array('/.+\.inc$/'); + + public static function viewSource($archive, $file) + { + // security, idea borrowed from PHK + if (!file_exists($archive . '.introspect')) { + header("HTTP/1.0 404 Not Found"); + return false; + } + if (self::_fileExists($archive, $_GET['viewsource'])) { + $source = highlight_file('phar://go-pear.phar/' . + $_GET['viewsource'], true); + header('Content-Type: text/html'); + header('Content-Length: ' . strlen($source)); + echo 'Source of ', + htmlspecialchars($_GET['viewsource']), ''; + echo '

Source of ', + htmlspecialchars($_GET['viewsource']), '

'; + if (isset($_GET['introspect'])) { + echo 'Return to ', htmlspecialchars($_GET['introspect']), '
'; + } + echo $source; + return false; + } else { + header("HTTP/1.0 404 Not Found"); + return false; + } + + } + + public static function introspect($archive, $dir) + { + // security, idea borrowed from PHK + if (!file_exists($archive . '.introspect')) { + header("HTTP/1.0 404 Not Found"); + return false; + } + if (!$dir) { + $dir = '/'; + } + $dir = self::processFile($dir); + if ($dir[0] != '/') { + $dir = '/' . $dir; + } + try { + $self = htmlspecialchars($_SERVER['PHP_SELF']); + $iterate = new DirectoryIterator('phar://go-pear.phar' . $dir); + echo 'Introspect ', htmlspecialchars($dir), + '

Introspect ', htmlspecialchars($dir), + '

+ + diff --git a/modules/support/templates/page-support.html b/modules/support/templates/page-support.html new file mode 100644 index 00000000..231cbc1b --- /dev/null +++ b/modules/support/templates/page-support.html @@ -0,0 +1,67 @@ +

{{lang_supIntro}}

+
+
+ {{lang_faq}} +
+ +
+
+ +
+
+ {{lang_content#1}} +
+
+
+
+ +
+
+ {{lang_content#2}} +
+
+
+ {{lang_showall}} +
+
+ + +
+
+ {{lang_form}} +
+
+
+ +
+ + +
+
+ + +
+
+ + + +

{{lang_helpInput}}

+
+ +
+
+
+ + diff --git a/modules/sysconfig.inc.php b/modules/sysconfig.inc.php deleted file mode 100644 index 8d19d62a..00000000 --- a/modules/sysconfig.inc.php +++ /dev/null @@ -1,391 +0,0 @@ -initAddModule(); - AddModule_Base::preprocess(); - } - - if ($action === 'module') { - // Action: "delmodule" (delete module) - if (Request::post('del', 'no') !== 'no') { - $this->delModule(); - } - if (Request::post('download', 'no') !== 'no') { - $this->downloadModule(); - } - if (Request::post('rebuild', 'no') !== 'no') { - $this->rebuildModule(); - } - } - - // Action: "addconfig" (compose config from one or more modules) - if ($action === 'addconfig') { - $this->initAddConfig(); - AddConfig_Base::preprocess(); - } - - if ($action === 'config') { - // Action: "delconfig" (delete config) - if (Request::post('del', 'no') !== 'no') { - $this->delConfig(); - } - // Action "activate" (set sysconfig as active) - if (Request::post('activate', 'no') !== 'no') { - $this->activateConfig(); - } - // Action "rebuild" (rebuild config.tgz from its modules) - if (Request::post('rebuild', 'no') !== 'no') { - $this->rebuildConfig(); - } - } - } - - /** - * Render module; called by main script when this module page should render - * its content. - */ - protected function doRender() - { - Render::setTitle(Dictionary::translate('lang_location')); - - $action = Request::any('action', 'list'); - switch ($action) { - case 'addmodule': - AddModule_Base::render(); - return; - case 'addconfig': - AddConfig_Base::render(); - return; - case 'list': - $this->listConfigs(); - return; - case 'module': - $listid = Request::post('list'); - if ($listid !== false) { - $this->listModuleContents($listid); - return; - } - break; - case 'config': - $listid = Request::post('list'); - if ($listid !== false) { - $this->listConfigContents($listid); - return; - } - break; - } - Message::addError('invalid-action', $action); - } - - /** - * If modules need updates (blue refresh buttons), we query their state - * via ajax, in case they are about to generate. This happens for example - * if you edit a module and a bunch of configs depend on it and will be - * rebuilt. - */ - protected function doAjax() - { - if (Request::post('action') === 'status') { - $mods = Request::post('mods'); - $confs = Request::post('confs'); - $outMods = array(); - $outConfs = array(); - $mods = explode(',', $mods); - $confs = explode(',', $confs); - // Mods - $string = '0'; - foreach ($mods as $mod) { - if (is_numeric($mod)) - $string .= ',' . $mod; - } - $res = Database::simpleQuery("SELECT moduleid FROM configtgz_module WHERE moduleid in ($string) AND status = 'OK'"); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $outMods[] = $row['moduleid']; - } - // Confs - $string = '0'; - foreach ($confs as $conf) { - if (is_numeric($conf)) - $string .= ',' . $conf; - } - $res = Database::simpleQuery("SELECT configid FROM configtgz WHERE configid in ($string) AND status = 'OK'"); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $outConfs[] = $row['configid']; - } - Header('Content-Type: application/json'); - die(json_encode(array('mods' => $outMods, 'confs' => $outConfs))); - } - } - - /** - * List all configurations and configuration modules. - */ - private function listConfigs() - { - // Configs - $res = Database::simpleQuery("SELECT configtgz.configid, configtgz.title, configtgz.filepath, configtgz.status, GROUP_CONCAT(configtgz_x_module.moduleid) AS modlist" - . " FROM configtgz" - . " INNER JOIN configtgz_x_module USING (configid)" - . " GROUP BY configid" - . " ORDER BY title ASC"); - $configs = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $configs[] = array( - 'configid' => $row['configid'], - 'config' => $row['title'], - 'modlist' => $row['modlist'], - 'current' => readlink(CONFIG_HTTP_DIR . '/default/config.tgz') === $row['filepath'], - 'needrebuild' => ($row['status'] !== 'OK') - ); - } - // Config modules - $res = Database::simpleQuery("SELECT moduleid, title, moduletype, status FROM configtgz_module ORDER BY moduletype ASC, title ASC"); - $modules = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $modules[] = array( - 'moduleid' => $row['moduleid'], - 'moduletype' => $row['moduletype'], - 'module' => $row['title'], - 'iscustom' => ($row['moduletype'] === 'CustomModule' || $row['moduletype'] === 'Branding'), - 'needrebuild' => ($row['status'] !== 'OK') - ); - } - Render::addTemplate('sysconfig/_page', array( - 'configs' => $configs, - 'modules' => $modules, - 'havemodules' => (count($modules) > 0) - )); - Render::addScriptTop('custom'); - Render::addFooter(''); - } - - private function listModuleContents($moduleid) - { - // fetch the data - $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); - if ($row === false) { - Message::addError('config-invalid', $moduleid); - Util::redirect('?do=SysConfig'); - } - - // find files in that archive - $status = Taskmanager::submit('ListArchive', array( - 'file' => $row['filepath'] - )); - if (isset($status['id'])) - $status = Taskmanager::waitComplete($status, 4000); - if (!Taskmanager::isFinished($status) || Taskmanager::isFailed($status)) { - Taskmanager::addErrorMessage($status); - Util::redirect('?do=SysConfig'); - } - - // Sort files for better display - $dirs = array(); - foreach ($status['data']['entries'] as $file) { - if ($file['isdir']) - continue; - $dirs[dirname($file['name'])][] = $file; - } - ksort($dirs); - $list = array(); - foreach ($dirs as $dir => $files) { - $list[] = array( - 'name' => $dir, - 'isdir' => true - ); - sort($files); - foreach ($files as $file) { - $file['size'] = Util::readableFileSize($file['size']); - $list[] = $file; - } - } - - // render the template - Render::addDialog(Dictionary::translate('lang_contentOf') . ' ' . $row['title'], false, 'sysconfig/custom-filelist', array( - 'files' => $list, - )); - } - - private function listConfigContents($configid) - { - // get config name - $config = Database::queryFirst("SELECT title FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid)); - if ($config === false) { - Message::addError('config-invalid', $configid); - Util::redirect('?do=SysConfig'); - } - // fetch the data - $res = Database::simpleQuery("SELECT module.moduleid, module.title AS moduletitle" - . " FROM configtgz_module module" - . " INNER JOIN configtgz_x_module USING (moduleid)" - . " WHERE configtgz_x_module.configid = :configid" - . " ORDER BY module.title ASC", array('configid' => $configid)); - - $modules = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $modules[] = array( - 'module' => $row['moduletitle'], - 'moduleid' => $row['moduleid'] - ); - } - - // render the template - Render::addDialog(Dictionary::translate('lang_contentOf') . ' ' . $config['title'], false, 'sysconfig/config-module-list', array( - 'modules' => $modules - )); - } - - private function activateConfig() - { - $configid = Request::post('activate', 'MISSING'); - $row = Database::queryFirst("SELECT title, filepath FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid)); - if ($row === false) { - Message::addError('config-invalid', $configid); - Util::redirect('?do=SysConfig'); - } - $task = Taskmanager::submit('LinkConfigTgz', array( - 'destination' => $row['filepath'] - )); - if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) { - $task = Taskmanager::waitComplete($task['id']); - } - if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) { - Message::addError('task-error', $task['data']['error']); - } elseif ($task['statusCode'] === TASK_FINISHED) { - Message::addSuccess('config-activated', $row['title']); - Event::activeConfigChanged(); - } - Util::redirect('?do=SysConfig'); - } - - private function rebuildConfig() - { - $configid = Request::post('rebuild', 'MISSING'); - $config = ConfigTgz::get($configid); - if ($config === false) { - Message::addError('config-invalid', $configid); - Util::redirect('?do=SysConfig'); - } - $ret = $config->generate(false, 350); // TODO - if ($ret === true) - Message::addSuccess('module-rebuilt', $config->title()); - elseif ($ret === false) - Message::addError('module-rebuild-failed', $config->title()); - else - Message::addInfo('module-rebuilding', $config->title()); - Util::redirect('?do=SysConfig'); - } - - private function delModule() - { - $moduleid = Request::post('del', 'MISSING'); - $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); - if ($row === false) { - Message::addError('config-invalid', $moduleid); - Util::redirect('?do=SysConfig'); - } - $existing = Database::queryFirst("SELECT title FROM configtgz_x_module" - . " INNER JOIN configtgz USING (configid)" - . " WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); - if ($existing !== false) { - Message::addError('module-in-use', $row['title'], $existing['title']); - Util::redirect('?do=SysConfig'); - } - $task = Taskmanager::submit('DeleteFile', array( - 'file' => $row['filepath'] - )); - if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) { - $task = Taskmanager::waitComplete($task['id']); - } - if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) { - Message::addWarning('task-error', $task['data']['error']); - } elseif ($task['statusCode'] === TASK_FINISHED) { - Message::addSuccess('module-deleted', $row['title']); - } - Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); - Util::redirect('?do=SysConfig'); - } - - private function downloadModule() - { - $moduleid = Request::post('download', 'MISSING'); - $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); - if ($row === false) { - Message::addError('config-invalid', $moduleid); - Util::redirect('?do=SysConfig'); - } - if (!Util::sendFile($row['filepath'], $row['title'] . '.tgz')) - Util::redirect('?do=SysConfig'); - exit(0); - } - - private function rebuildModule() - { - $moduleid = Request::post('rebuild', 'MISSING'); - $module = ConfigModule::get($moduleid); - if ($module === false) { - Message::addError('config-invalid', $moduleid); - Util::redirect('?do=SysConfig'); - } - $ret = $module->generate(false, 250); - if ($ret === true) - Message::addSuccess('module-rebuilt', $module->title()); - elseif ($ret === false) - Message::addError('module-rebuild-failed', $module->title()); - else - Message::addInfo('module-rebuilding', $module->title()); - Util::redirect('?do=SysConfig'); - } - - private function delConfig() - { - $configid = Request::post('del', 'MISSING'); - $config = ConfigTgz::get($configid); - if ($config === false) { - Message::addError('config-invalid', $configid); - Util::redirect('?do=SysConfig'); - } - $config->delete(); - Util::redirect('?do=SysConfig'); - } - - private function initAddModule() - { - ConfigModule::loadDb(); - require_once 'modules/sysconfig/addmodule.inc.php'; - $step = Request::any('step', 'AddModule_Start'); - if (!class_exists($step) && preg_match('/^([a-zA-Z0-9]+)_/', $step, $out)) { - require_once 'modules/sysconfig/addmodule_' . strtolower($out[1]) . '.inc.php'; - } - AddModule_Base::setStep($step); - } - - private function initAddConfig() - { - ConfigModule::loadDb(); - require_once 'modules/sysconfig/addconfig.inc.php'; - $step = Request::any('step', 0); - if ($step === 0) - $step = 'AddConfig_Start'; - AddConfig_Base::setStep($step); - } - -} diff --git a/modules/sysconfig/addconfig.inc.php b/modules/sysconfig/addconfig.inc.php index e51a7f64..8203e555 100644 --- a/modules/sysconfig/addconfig.inc.php +++ b/modules/sysconfig/addconfig.inc.php @@ -170,7 +170,7 @@ class AddConfig_Start extends AddConfig_Base } } unset($mod); - Render::addDialog(Dictionary::translate("lang_configurationCompilation"), false, 'sysconfig/cfg-start', array( + Render::addDialog(Dictionary::translate("lang_configurationCompilation"), false, 'cfg-start', array( 'step' => 'AddConfig_Finish', 'groups' => array_values($modGroups), 'title' => $title, @@ -213,7 +213,7 @@ class AddConfig_Finish extends AddConfig_Base protected function renderInternal() { - Render::addDialog(Dictionary::translate('lang_configurationCompilation'), false, 'sysconfig/cfg-finish', array( + Render::addDialog(Dictionary::translate('lang_configurationCompilation'), false, 'cfg-finish', array( 'configid' => $this->config->id() )); } diff --git a/modules/sysconfig/addmodule.inc.php b/modules/sysconfig/addmodule.inc.php index a20bda37..bcd8e796 100644 --- a/modules/sysconfig/addmodule.inc.php +++ b/modules/sysconfig/addmodule.inc.php @@ -18,35 +18,6 @@ abstract class AddModule_Base * @var \ConfigModule */ protected $edit = false; - - protected $bag = false; - - private $bagId = false; - - protected function loadBag($createIfNone = true) - { - if ($this->bagId !== false) - return $this->bagId; - $bagId = Request::any('bag', '', 'string'); - $this->bag = Session::get($bagId); - if ($this->bag === false) { - if (!$createIfNone) - return false; - $this->bagId = dechex(rand()); - $this->bag = array(); - } else { - $this->bagId = $bagId; - } - return $this->bagId; - } - - protected function saveBag() - { - if ($this->bagId === false) - return false; - Session::set($this->bagId, $this->bag); - return true; - } /** * @@ -160,7 +131,7 @@ class AddModule_Start extends AddModule_Base $order[] = $module['sortOrder']; } array_multisort($order, SORT_ASC, $title, SORT_ASC, $mods); - Render::addDialog(Dictionary::translate('lang_moduleAdd'), false, 'sysconfig/start', array('modules' => array_values($mods))); + Render::addDialog(Dictionary::translate('lang_moduleAdd'), false, 'start', array('modules' => array_values($mods))); } } diff --git a/modules/sysconfig/addmodule_adauth.inc.php b/modules/sysconfig/addmodule_adauth.inc.php index cba09382..e295630c 100644 --- a/modules/sysconfig/addmodule_adauth.inc.php +++ b/modules/sysconfig/addmodule_adauth.inc.php @@ -25,7 +25,7 @@ class AdAuth_Start extends AddModule_Base $data['server'] = $out[1]; } $data['step'] = 'AdAuth_CheckConnection'; - Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'sysconfig/ad-start', $data); + Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'ad-start', $data); } } @@ -88,7 +88,7 @@ class AdAuth_CheckConnection extends AddModule_Base } else { $data['next'] = 'AdAuth_CheckCredentials'; } - Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'sysconfig/ad_ldap-checkconnection', $data); + Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'ad_ldap-checkconnection', $data); } } @@ -165,7 +165,7 @@ class AdAuth_SelfSearch extends AddModule_Base } else { $data['next'] = 'AdAuth_CheckCredentials'; } - Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'sysconfig/ad-selfsearch', + Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'ad-selfsearch', array_merge($this->taskIds, $data)); } @@ -218,7 +218,7 @@ class AdAuth_HomeAttrCheck extends AddModule_Base protected function renderInternal() { - Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'sysconfig/ad-selfsearch', array_merge($this->taskIds, array( + Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'ad-selfsearch', array_merge($this->taskIds, array( 'edit' => Request::post('edit'), 'title' => Request::post('title'), 'server' => Request::post('server'), @@ -289,7 +289,7 @@ class AdAuth_CheckCredentials extends AddModule_Base protected function renderInternal() { - Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'sysconfig/ad_ldap-checkcredentials', array_merge($this->taskIds, array( + Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'ad_ldap-checkcredentials', array_merge($this->taskIds, array( 'edit' => Request::post('edit'), 'title' => Request::post('title'), 'server' => Request::post('server') . ':' . Request::post('port'), @@ -303,24 +303,23 @@ class AdAuth_CheckCredentials extends AddModule_Base 'certificate' => Request::post('certificate', ''), 'originalbinddn' => Request::post('originalbinddn'), 'prev' => 'AdAuth_Start', - 'next' => 'AdAuth_HomeDir' + 'next' => 'AdAuth_Finish' )) ); } } -class AdAuth_HomeDir extends AddModule_Base +class AdAuth_Finish extends AddModule_Base { - private $searchbase; - private $binddn; - + private $taskIds; + protected function preprocessInternal() { - $this->binddn = Request::post('binddn'); - $this->searchbase = Request::post('searchbase'); - if (empty($this->searchbase)) { + $binddn = Request::post('binddn'); + $searchbase = Request::post('searchbase'); + if (empty($searchbase)) { // If no search base was given, determine it from the dn $originalBindDn = str_replace('\\', '/', trim(Request::post('originalbinddn'))); if (!preg_match('#^([^/]+)/[^/]+$#', $originalBindDn, $out)) { @@ -328,81 +327,25 @@ class AdAuth_HomeDir extends AddModule_Base Util::redirect('?do=SysConfig&action=addmodule&step=AdAuth_Start'); } // $out[1] is the domain // Find the domain in the dn - $i = mb_stripos($this->binddn, '=' . $out[1] . ','); + $i = mb_stripos($binddn, '=' . $out[1] . ','); if ($i === false) { Message::addError('value-invalid', 'binddn', $out[1]); Util::redirect('?do=SysConfig&action=addmodule&step=AdAuth_Start'); } // Now find ',' before it so we get the key - $i = mb_strrpos(mb_substr($this->binddn, 0, $i), ','); + $i = mb_strrpos(mb_substr($binddn, 0, $i), ','); if ($i === false) $i = -1; - $this->searchbase = mb_substr($this->binddn, $i + 1); + $searchbase = mb_substr($binddn, $i + 1); } else { $somedn = Request::post('somedn', false); if (!empty($somedn)) { - $i = stripos($somedn, $this->searchbase); + $i = stripos($somedn, $searchbase); if ($i !== false) { - $this->searchbase = substr($somedn, $i, strlen($this->searchbase)); - } - } - } - } - - protected function renderInternal() - { - $data = array( - 'edit' => Request::post('edit'), - 'title' => Request::post('title'), - 'server' => Request::post('server'), - 'searchbase' => $this->searchbase, - 'binddn' => $this->binddn, - 'bindpw' => Request::post('bindpw'), - 'home' => Request::post('home'), - 'homeattr' => Request::post('homeattr'), - 'ssl' => Request::post('ssl') === 'on', - 'fingerprint' => Request::post('fingerprint'), - 'certificate' => Request::post('certificate', ''), - 'originalbinddn' => Request::post('originalbinddn'), - 'prev' => 'AdAuth_Start', - 'next' => 'AdAuth_Finish' - ); - if ($this->edit !== false) { - foreach (self::getAttributes() as $key) { - if ($this->edit->getData($key)) { - $data[$key . '_c'] = 'checked="checked"'; + $searchbase = substr($somedn, $i, strlen($searchbase)); } } - $data['shareRemapMode_' . $this->edit->getData('shareRemapMode')] = 'selected="selected"'; - $letter = $this->edit->getData('shareHomeDrive'); - } else { - $data['shareDownloads'] = $data['shareMedia'] = $data['shareDocuments'] = 'selected="selected"'; - $letter = 'H:'; } - $data['drives'] = array(); - foreach (range('D', 'Z') as $l) { - $data['drives'][] = array( - 'drive' => $l . ':', - 'selected' => (strtoupper($letter{0}) === $l) ? 'selected="selected"' : '' - ); - } - Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'sysconfig/ad_ldap-homedir', $data); - } - - public static function getAttributes() - { - return array('shareRemapMode', 'shareRemapCreate', 'shareDocuments', 'shareDownloads', 'shareDesktop', 'shareMedia', 'shareOther', 'shareHomeDrive'); - } - -} - -class AdAuth_Finish extends AddModule_Base -{ - - private $taskIds; - - protected function preprocessInternal() - { $title = Request::post('title'); if (empty($title)) $title = 'AD: ' . Request::post('server'); @@ -412,24 +355,13 @@ class AdAuth_Finish extends AddModule_Base $module = $this->edit; $ssl = Request::post('ssl', 'off') === 'on'; $module->setData('server', Request::post('server')); - $module->setData('searchbase', Request::post('searchbase')); - $module->setData('binddn', Request::post('binddn')); + $module->setData('searchbase', $searchbase); + $module->setData('binddn', $binddn); $module->setData('bindpw', Request::post('bindpw')); $module->setData('home', Request::post('home')); $module->setData('homeattr', Request::post('homeattr')); $module->setData('certificate', Request::post('certificate')); $module->setData('ssl', $ssl); - foreach (AdAuth_HomeDir::getAttributes() as $key) { - $value = Request::post($key); - if (is_numeric($value)) { - settype($value, 'integer'); - } elseif ($value === 'on') { - $value = 1; - } elseif ($value === false) { - $value = 0; - } - $module->setData($key, $value); - } if ($ssl) { $module->setData('fingerprint', Request::post('fingerprint', '')); } else { @@ -475,7 +407,7 @@ class AdAuth_Finish extends AddModule_Base protected function renderInternal() { - Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'sysconfig/ad-finish', $this->taskIds); + Render::addDialog(Dictionary::translate('config-module', 'adAuth_title'), false, 'ad-finish', $this->taskIds); } } diff --git a/modules/sysconfig/addmodule_branding.inc.php b/modules/sysconfig/addmodule_branding.inc.php index 336e2a77..67e20892 100644 --- a/modules/sysconfig/addmodule_branding.inc.php +++ b/modules/sysconfig/addmodule_branding.inc.php @@ -10,7 +10,7 @@ class Branding_Start extends AddModule_Base protected function renderInternal() { Render::addScriptBottom('fileselect'); - Render::addDialog(Dictionary::translate('config-module', 'branding_title'), false, 'sysconfig/branding-start', array( + Render::addDialog(Dictionary::translate('config-module', 'branding_title'), false, 'branding-start', array( 'step' => 'Branding_ProcessFile', 'edit' => $this->edit ? $this->edit->id() : false )); @@ -76,7 +76,7 @@ class Branding_ProcessFile extends AddModule_Base $png = base64_encode(file_get_contents($this->task['data']['pngFile'])); if (filesize($this->svgFile) < 1000000) $svg = base64_encode(file_get_contents($this->svgFile)); - Render::addDialog(Dictionary::translate('config-module', 'branding_title'), false, 'sysconfig/branding-check', array( + Render::addDialog(Dictionary::translate('config-module', 'branding_title'), false, 'branding-check', array( 'png' => $png, 'svg' => $svg, 'error' => $this->task['data']['error'], diff --git a/modules/sysconfig/addmodule_custommodule.inc.php b/modules/sysconfig/addmodule_custommodule.inc.php index f7342b7b..023463f7 100644 --- a/modules/sysconfig/addmodule_custommodule.inc.php +++ b/modules/sysconfig/addmodule_custommodule.inc.php @@ -13,7 +13,7 @@ class CustomModule_Start extends AddModule_Base { Session::set('mod_temp', false); Render::addScriptBottom('fileselect'); - Render::addDialog(Dictionary::translate('config-module', 'custom_title'), false, 'sysconfig/custom-upload', array( + Render::addDialog(Dictionary::translate('config-module', 'custom_title'), false, 'custom-upload', array( 'step' => 'CustomModule_ProcessUpload', 'edit' => $this->edit ? $this->edit->id() : false )); @@ -92,7 +92,7 @@ class CustomModule_ProcessUpload extends AddModule_Base $title = basename($_FILES['modulefile']['name']); else $title = ''; - Render::addDialog(Dictionary::translate('config-module', 'custom_title'), false, 'sysconfig/custom-fileselect', array( + Render::addDialog(Dictionary::translate('config-module', 'custom_title'), false, 'custom-fileselect', array( 'step' => 'CustomModule_CompressModule', 'files' => $list, 'edit' => $this->edit ? $this->edit->id() : false, diff --git a/modules/sysconfig/addmodule_ldapauth.inc.php b/modules/sysconfig/addmodule_ldapauth.inc.php index 0dad780b..e17469a0 100644 --- a/modules/sysconfig/addmodule_ldapauth.inc.php +++ b/modules/sysconfig/addmodule_ldapauth.inc.php @@ -21,7 +21,7 @@ class LdapAuth_Start extends AddModule_Base $data['server'] = $out[1]; } $data['step'] = 'LdapAuth_CheckConnection'; - Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'sysconfig/ldap-start', $data); + Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'ldap-start', $data); } } @@ -77,7 +77,7 @@ class LdapAuth_CheckConnection extends AddModule_Base ); $data['prev'] = 'LdapAuth_Start'; $data['next'] = 'LdapAuth_CheckCredentials'; - Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'sysconfig/ad_ldap-checkconnection', $data); + Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'ad_ldap-checkconnection', $data); } } @@ -133,7 +133,7 @@ class LdapAuth_CheckCredentials extends AddModule_Base protected function renderInternal() { - Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'sysconfig/ad_ldap-checkcredentials', array_merge($this->taskIds, array( + Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'ad_ldap-checkcredentials', array_merge($this->taskIds, array( 'edit' => Request::post('edit'), 'title' => Request::post('title'), 'server' => Request::post('server') . ':' . Request::post('port'), @@ -145,73 +145,9 @@ class LdapAuth_CheckCredentials extends AddModule_Base 'fingerprint' => Request::post('fingerprint'), 'certificate' => Request::post('certificate', ''), 'prev' => 'LdapAuth_Start', - 'next' => 'LdapAuth_HomeDir' - )) - ); - } - -} - -class LdapAuth_HomeDir extends AddModule_Base -{ - - private $searchbase; - - protected function preprocessInternal() - { - $this->searchbase = Request::post('searchbase'); - $somedn = Request::post('somedn', false); - if (!empty($somedn)) { - $i = stripos($somedn, $this->searchbase); - if ($i !== false) { - $this->searchbase = substr($somedn, $i, strlen($this->searchbase)); - } - } - } - - protected function renderInternal() - { - $data = array( - 'edit' => Request::post('edit'), - 'title' => Request::post('title'), - 'server' => Request::post('server'), - 'searchbase' => $this->searchbase, - 'binddn' => Request::post('binddn'), - 'bindpw' => Request::post('bindpw'), - 'home' => Request::post('home'), - 'homeattr' => Request::post('homeattr'), - 'ssl' => Request::post('ssl') === 'on', - 'fingerprint' => Request::post('fingerprint'), - 'certificate' => Request::post('certificate', ''), - 'originalbinddn' => Request::post('originalbinddn'), - 'prev' => 'LdapAuth_Start', 'next' => 'LdapAuth_Finish' + )) ); - if ($this->edit !== false) { - foreach (self::getAttributes() as $key) { - if ($this->edit->getData($key)) { - $data[$key . '_c'] = 'checked="checked"'; - } - } - $data['shareRemapMode_' . $this->edit->getData('shareRemapMode')] = 'selected="selected"'; - $letter = $this->edit->getData('shareHomeDrive'); - } else { - $data['shareDownloads'] = $data['shareMedia'] = $data['shareDocuments'] = 'selected="selected"'; - $letter = 'H:'; - } - $data['drives'] = array(); - foreach (range('D', 'Z') as $l) { - $data['drives'][] = array( - 'drive' => $l . ':', - 'selected' => (strtoupper($letter{0}) === $l) ? 'selected="selected"' : '' - ); - } - Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'sysconfig/ad_ldap-homedir', $data); - } - - public static function getAttributes() - { - return array('shareRemapMode', 'shareRemapCreate', 'shareDocuments', 'shareDownloads', 'shareDesktop', 'shareMedia', 'shareOther', 'shareHomeDrive'); } } @@ -232,6 +168,13 @@ class LdapAuth_Finish extends AddModule_Base $module = ConfigModule::getInstance('LdapAuth'); else $module = $this->edit; + $somedn = Request::post('somedn', false); + if (!empty($somedn)) { + $i = stripos($somedn, $searchbase); + if ($i !== false) { + $searchbase = substr($somedn, $i, strlen($searchbase)); + } + } $ssl = Request::post('ssl', 'off') === 'on'; $module->setData('server', Request::post('server')); $module->setData('searchbase', $searchbase); @@ -240,17 +183,6 @@ class LdapAuth_Finish extends AddModule_Base $module->setData('home', Request::post('home')); $module->setData('certificate', Request::post('certificate')); $module->setData('ssl', $ssl); - foreach (LdapAuth_HomeDir::getAttributes() as $key) { - $value = Request::post($key); - if (is_numeric($value)) { - settype($value, 'integer'); - } elseif ($value === 'on') { - $value = 1; - } elseif ($value === false) { - $value = 0; - } - $module->setData($key, $value); - } if ($ssl) { $module->setData('fingerprint', Request::post('fingerprint', '')); } else { @@ -296,7 +228,7 @@ class LdapAuth_Finish extends AddModule_Base protected function renderInternal() { - Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'sysconfig/ldap-finish', $this->taskIds); + Render::addDialog(Dictionary::translate('config-module', 'ldapAuth_title'), false, 'ldap-finish', $this->taskIds); } } diff --git a/modules/sysconfig/addmodule_sshconfig.inc.php b/modules/sysconfig/addmodule_sshconfig.inc.php index e50ca72c..5f0f7222 100644 --- a/modules/sysconfig/addmodule_sshconfig.inc.php +++ b/modules/sysconfig/addmodule_sshconfig.inc.php @@ -18,7 +18,7 @@ class SshConfig_Start extends AddModule_Base } else { $data = array(); } - Render::addDialog(Dictionary::translate('lang_clientSshConfig'), false, 'sysconfig/sshconfig-start', $data + array( + Render::addDialog(Dictionary::translate('lang_clientSshConfig'), false, 'sshconfig-start', $data + array( 'step' => 'SshConfig_Finish', )); } diff --git a/modules/sysconfig/config.json b/modules/sysconfig/config.json new file mode 100644 index 00000000..93209f62 --- /dev/null +++ b/modules/sysconfig/config.json @@ -0,0 +1,4 @@ +{ + "category":"settings", + "enabled":"true" +} diff --git a/modules/sysconfig/module.inc.php b/modules/sysconfig/module.inc.php new file mode 100644 index 00000000..0c06e125 --- /dev/null +++ b/modules/sysconfig/module.inc.php @@ -0,0 +1,396 @@ + $startClass, + 'title' => $title, + 'description' => $description, + 'group' => $group, + 'unique' => $unique, + 'sortOrder' => $sortOrder + ); + } + + /** + * + * @return array All registered module types + */ + public static function getModuleTypes() + { + return self::$moduleTypes; + } + + protected function doPreprocess() + { + User::load(); + + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=Main'); + } + + $action = Request::any('action', 'list'); + + // Load all addmodule classes, as they populate the $moduleTypes array + require_once 'modules/sysconfig/addmodule.inc.php'; + foreach (glob('modules/sysconfig/addmodule_*.inc.php') as $file) { + require_once $file; + } + + // Action: "addmodule" (upload new module) + if ($action === 'addmodule') { + $this->initAddModule(); + AddModule_Base::preprocess(); + } + + if ($action === 'module') { + // Action: "delmodule" (delete module) + if (Request::post('del', 'no') !== 'no') { + $this->delModule(); + } + if (Request::post('download', 'no') !== 'no') { + $this->downloadModule(); + } + if (Request::post('rebuild', 'no') !== 'no') { + $this->rebuildModule(); + } + } + + // Action: "addconfig" (compose config from one or more modules) + if ($action === 'addconfig') { + $this->initAddConfig(); + AddConfig_Base::preprocess(); + } + + if ($action === 'config') { + // Action: "delconfig" (delete config) + if (Request::post('del', 'no') !== 'no') { + $this->delConfig(); + } + // Action "activate" (set sysconfig as active) + if (Request::post('activate', 'no') !== 'no') { + $this->activateConfig(); + } + // Action "rebuild" (rebuild config.tgz from its modules) + if (Request::post('rebuild', 'no') !== 'no') { + $this->rebuildConfig(); + } + } + } + + /** + * Render module; called by main script when this module page should render + * its content. + */ + protected function doRender() + { + Render::setTitle(Dictionary::translate('lang_location')); + + $action = Request::any('action', 'list'); + switch ($action) { + case 'addmodule': + AddModule_Base::render(); + return; + case 'addconfig': + AddConfig_Base::render(); + return; + case 'list': + $this->listConfigs(); + return; + case 'module': + $listid = Request::post('list'); + if ($listid !== false) { + $this->listModuleContents($listid); + return; + } + break; + case 'config': + $listid = Request::post('list'); + if ($listid !== false) { + $this->listConfigContents($listid); + return; + } + break; + } + Message::addError('invalid-action', $action, 'main'); + } + + /** + * List all configurations and configuration modules. + */ + private function listConfigs() + { + // Configs + $res = Database::simpleQuery("SELECT configtgz.configid, configtgz.title, configtgz.filepath, configtgz.status, GROUP_CONCAT(configtgz_x_module.moduleid) AS modlist" + . " FROM configtgz" + . " INNER JOIN configtgz_x_module USING (configid)" + . " GROUP BY configid" + . " ORDER BY title ASC"); + $configs = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $configs[] = array( + 'configid' => $row['configid'], + 'config' => $row['title'], + 'modlist' => $row['modlist'], + 'current' => readlink(CONFIG_HTTP_DIR . '/default/config.tgz') === $row['filepath'], + 'needrebuild' => ($row['status'] !== 'OK') + ); + } + // Config modules + $res = Database::simpleQuery("SELECT moduleid, title, moduletype, status FROM configtgz_module ORDER BY moduletype ASC, title ASC"); + $modules = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $modules[] = array( + 'moduleid' => $row['moduleid'], + 'moduletype' => $row['moduletype'], + 'module' => $row['title'], + 'iscustom' => ($row['moduletype'] === 'CustomModule' || $row['moduletype'] === 'Branding'), + 'needrebuild' => ($row['status'] !== 'OK') + ); + } + Render::addTemplate('_page', array( + 'configs' => $configs, + 'modules' => $modules, + 'havemodules' => (count($modules) > 0) + )); + Render::addScriptTop('custom'); + Render::addFooter(''); + } + + private function listModuleContents($moduleid) + { + // fetch the data + $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); + if ($row === false) { + Message::addError('config-invalid', $moduleid); + Util::redirect('?do=SysConfig'); + } + + // find files in that archive + $status = Taskmanager::submit('ListArchive', array( + 'file' => $row['filepath'] + )); + if (isset($status['id'])) + $status = Taskmanager::waitComplete($status, 4000); + if (!Taskmanager::isFinished($status) || Taskmanager::isFailed($status)) { + Taskmanager::addErrorMessage($status); + Util::redirect('?do=SysConfig'); + } + + // Sort files for better display + $dirs = array(); + foreach ($status['data']['entries'] as $file) { + if ($file['isdir']) + continue; + $dirs[dirname($file['name'])][] = $file; + } + ksort($dirs); + $list = array(); + foreach ($dirs as $dir => $files) { + $list[] = array( + 'name' => $dir, + 'isdir' => true + ); + sort($files); + foreach ($files as $file) { + $file['size'] = Util::readableFileSize($file['size']); + $list[] = $file; + } + } + + // render the template + Render::addDialog(Dictionary::translate('lang_contentOf') . ' ' . $row['title'], false, 'custom-filelist', array( + 'files' => $list, + )); + } + + private function listConfigContents($configid) + { + // get config name + $config = Database::queryFirst("SELECT title FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid)); + if ($config === false) { + Message::addError('config-invalid', $configid); + Util::redirect('?do=SysConfig'); + } + // fetch the data + $res = Database::simpleQuery("SELECT module.moduleid, module.title AS moduletitle" + . " FROM configtgz_module module" + . " INNER JOIN configtgz_x_module USING (moduleid)" + . " WHERE configtgz_x_module.configid = :configid" + . " ORDER BY module.title ASC", array('configid' => $configid)); + + $modules = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $modules[] = array( + 'module' => $row['moduletitle'], + 'moduleid' => $row['moduleid'] + ); + } + + // render the template + Render::addDialog(Dictionary::translate('lang_contentOf') . ' ' . $config['title'], false, 'config-module-list', array( + 'modules' => $modules + )); + } + + private function activateConfig() + { + $configid = Request::post('activate', 'MISSING'); + $row = Database::queryFirst("SELECT title, filepath FROM configtgz WHERE configid = :configid LIMIT 1", array('configid' => $configid)); + if ($row === false) { + Message::addError('config-invalid', $configid); + Util::redirect('?do=SysConfig'); + } + $task = Taskmanager::submit('LinkConfigTgz', array( + 'destination' => $row['filepath'] + )); + if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) { + $task = Taskmanager::waitComplete($task['id']); + } + if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) { + Message::addError('task-error', $task['data']['error']); + } elseif ($task['statusCode'] === TASK_FINISHED) { + Message::addSuccess('config-activated', $row['title']); + Event::activeConfigChanged(); + } + Util::redirect('?do=SysConfig'); + } + + private function rebuildConfig() + { + $configid = Request::post('rebuild', 'MISSING'); + $config = ConfigTgz::get($configid); + if ($config === false) { + Message::addError('config-invalid', $configid); + Util::redirect('?do=SysConfig'); + } + $ret = $config->generate(false, 350); // TODO + if ($ret === true) + Message::addSuccess('module-rebuilt', $config->title()); + elseif ($ret === false) + Message::addError('module-rebuild-failed', $config->title()); + else + Message::addInfo('module-rebuilding', $config->title()); + Util::redirect('?do=SysConfig'); + } + + private function delModule() + { + $moduleid = Request::post('del', 'MISSING'); + $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); + if ($row === false) { + Message::addError('config-invalid', $moduleid); + Util::redirect('?do=SysConfig'); + } + $existing = Database::queryFirst("SELECT title FROM configtgz_x_module" + . " INNER JOIN configtgz USING (configid)" + . " WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); + if ($existing !== false) { + Message::addError('module-in-use', $row['title'], $existing['title']); + Util::redirect('?do=SysConfig'); + } + $task = Taskmanager::submit('DeleteFile', array( + 'file' => $row['filepath'] + )); + if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) { + $task = Taskmanager::waitComplete($task['id']); + } + if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) { + Message::addWarning('task-error', $task['data']['error']); + } elseif ($task['statusCode'] === TASK_FINISHED) { + Message::addSuccess('module-deleted', $row['title']); + } + Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); + Util::redirect('?do=SysConfig'); + } + + private function downloadModule() + { + $moduleid = Request::post('download', 'MISSING'); + $row = Database::queryFirst("SELECT title, filepath FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid)); + if ($row === false) { + Message::addError('config-invalid', $moduleid); + Util::redirect('?do=SysConfig'); + } + if (!Util::sendFile($row['filepath'], $row['title'] . '.tgz')) + Util::redirect('?do=SysConfig'); + exit(0); + } + + private function rebuildModule() + { + $moduleid = Request::post('rebuild', 'MISSING'); + $module = ConfigModule::get($moduleid); + if ($module === false) { + Message::addError('config-invalid', $moduleid); + Util::redirect('?do=SysConfig'); + } + $ret = $module->generate(false, 250); + if ($ret === true) + Message::addSuccess('module-rebuilt', $module->title()); + elseif ($ret === false) + Message::addError('module-rebuild-failed', $module->title()); + else + Message::addInfo('module-rebuilding', $module->title()); + Util::redirect('?do=SysConfig'); + } + + private function delConfig() + { + $configid = Request::post('del', 'MISSING'); + $config = ConfigTgz::get($configid); + if ($config === false) { + Message::addError('config-invalid', $configid); + Util::redirect('?do=SysConfig'); + } + $config->delete(); + Util::redirect('?do=SysConfig'); + } + + private function initAddModule() + { + ConfigModule::loadDb(); + require_once 'modules/sysconfig/addmodule.inc.php'; + $step = Request::any('step', 'AddModule_Start'); + if (!class_exists($step) && preg_match('/^([a-zA-Z0-9]+)_/', $step, $out)) { + require_once 'modules/sysconfig/addmodule_' . strtolower($out[1]) . '.inc.php'; + } + AddModule_Base::setStep($step); + } + + private function initAddConfig() + { + ConfigModule::loadDb(); + require_once 'modules/sysconfig/addconfig.inc.php'; + $step = Request::any('step', 0); + if ($step === 0) + $step = 'AddConfig_Start'; + AddConfig_Base::setStep($step); + } + +} diff --git a/modules/sysconfig/templates/_page.html b/modules/sysconfig/templates/_page.html new file mode 100644 index 00000000..1a2f64d6 --- /dev/null +++ b/modules/sysconfig/templates/_page.html @@ -0,0 +1,227 @@ +
+
+
+
+ {{lang_availableSystem}} + +
+
+
+ + + + {{#configs}} + + + + + + + {{/configs}} +
+
{{config}}
+
+ {{^current}} + + {{/current}} + {{#current}} + + + {{lang_active}} + + {{/current}} + + + + + +
+ {{^configs}} +
+ {{lang_systemConfigurationNotFound}} +
+ {{^modules}} +
+ {{lang_systemConfigurationAlert}} +
+ {{/modules}} + {{/configs}} +
+
+ {{#havemodules}} + + {{/havemodules}} +
+
+ +
+
+
+ {{lang_availableModules}} + +
+
+
+ + + + {{#modules}} + + + + + + + {{/modules}} +
{{moduletype}}
{{module}}
+ {{#iscustom}} + + + + {{/iscustom}} + + + + +
+ {{^modules}} +
{{lang_configurationModuleNotFound}}
+ {{/modules}} +
+
+ +
+
+
+ +
+
{{lang_legend}}
+
+

+ + {{lang_showLong}} +

+

+ + {{lang_downloadLong}} +

+

+ + {{lang_rebuildLong}} +

+

+ + {{lang_rebuildOutdatedLong}} +

+

+ + {{lang_editLong}} +

+
+ + {{lang_deleteLong}} +
+
+
+ + + + + + \ No newline at end of file diff --git a/modules/sysconfig/templates/ad-finish.html b/modules/sysconfig/templates/ad-finish.html new file mode 100644 index 00000000..f73cad9d --- /dev/null +++ b/modules/sysconfig/templates/ad-finish.html @@ -0,0 +1,29 @@ +

+ {{lang_adStarted}} +

+ +
+
{{lang_generateModule}}
+
+
+ + + diff --git a/modules/sysconfig/templates/ad-selfsearch.html b/modules/sysconfig/templates/ad-selfsearch.html new file mode 100644 index 00000000..76952dc3 --- /dev/null +++ b/modules/sysconfig/templates/ad-selfsearch.html @@ -0,0 +1,112 @@ +

+ {{lang_dnLookup}} +

+ +
+
LDAP Self-Query
+ + +
+{{lang_onProblemSearchBase}} +

+
+
+ + + + + + + + + + {{#ssl}} + + + {{/ssl}} + +
+
+
+
+ + + + + + + + + + + + {{#ssl}} + + + {{/ssl}} + + +
+
+ diff --git a/modules/sysconfig/templates/ad-start.html b/modules/sysconfig/templates/ad-start.html new file mode 100644 index 00000000..98546140 --- /dev/null +++ b/modules/sysconfig/templates/ad-start.html @@ -0,0 +1,121 @@ +

+ {{lang_adText1}} +
+ {{lang_adText2}} +
+ {{lang_adText3}} +

+
dsquery user -name "Username"
+

+ {{lang_adText4}} +

+ +{{lang_asteriskMandatory}} + +
+ + + + +
+ {{lang_moduleTitle}} + +
+
+ Server * + +
+
+ {{lang_bindDN}} * + +
+
+ {{lang_password}} * + +
+
+ {{lang_searchBase}} + +
+
+
+ Home + + + + +
+
+ {{lang_homeAttr}} + + + + +
+
+
+ +
+ {{lang_sslDescription}} +
+
+ +
+
+
+
+
+ {{lang_customCertificate}} +
+-----BEGIN CERTIFICATE-----
+MIIFfTCCA...
+.....
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+.....
+-----END CERTIFICATE-----
+ +
+
+ +
+
+
+
+ + + + diff --git a/modules/sysconfig/templates/ad_ldap-checkconnection.html b/modules/sysconfig/templates/ad_ldap-checkconnection.html new file mode 100644 index 00000000..5925829a --- /dev/null +++ b/modules/sysconfig/templates/ad_ldap-checkconnection.html @@ -0,0 +1,91 @@ +

+ {{lang_connectionWait}} +

+ +
+
Port Check
+
+ + + +
+
+
+ + + + + + + + + + {{#ssl}} + + + {{/ssl}} + +
+
+
+
+ + + + + + + + + + + {{#ssl}} + + + + {{/ssl}} + + +
+
+
+ diff --git a/modules/sysconfig/templates/ad_ldap-checkcredentials.html b/modules/sysconfig/templates/ad_ldap-checkcredentials.html new file mode 100644 index 00000000..0586209b --- /dev/null +++ b/modules/sysconfig/templates/ad_ldap-checkcredentials.html @@ -0,0 +1,67 @@ +

+ {{lang_connectionWait}} +

+ +
+
LDAP Test-Query
+
+{{lang_onProblemSearchBase}} +

+
+
+ + + + + + + + + + {{#ssl}} + + + {{/ssl}} + +
+
+
+
+ + + + + + + + + + + {{#ssl}} + + + {{/ssl}} + + + +
+
+ diff --git a/modules/sysconfig/templates/branding-check.html b/modules/sysconfig/templates/branding-check.html new file mode 100644 index 00000000..8f6ef055 --- /dev/null +++ b/modules/sysconfig/templates/branding-check.html @@ -0,0 +1,26 @@ +

+ {{lang_brandingInfo}} +

+
+ {{#svg}} + + {{/svg}} +
+
+ {{#png}} + + {{/png}} +
+
+
{{error}}
+
+
+ + +
+ + +
+ +
+
diff --git a/modules/sysconfig/templates/branding-start.html b/modules/sysconfig/templates/branding-start.html new file mode 100644 index 00000000..09b9ca27 --- /dev/null +++ b/modules/sysconfig/templates/branding-start.html @@ -0,0 +1,25 @@ +

+ {{lang_branding}} +

+
+ + +
+ + +
+ {{lang_or}} +
+ +
+ + + + {{lang_browseForFile}}… + + +
+
+ +
+ diff --git a/modules/sysconfig/templates/cfg-finish.html b/modules/sysconfig/templates/cfg-finish.html new file mode 100644 index 00000000..a6e51996 --- /dev/null +++ b/modules/sysconfig/templates/cfg-finish.html @@ -0,0 +1,12 @@ +

+ {{lang_configurationSuccess}} +

+ +
+ + + +
+ +
+
diff --git a/modules/sysconfig/templates/cfg-start.html b/modules/sysconfig/templates/cfg-start.html new file mode 100644 index 00000000..50f366ea --- /dev/null +++ b/modules/sysconfig/templates/cfg-start.html @@ -0,0 +1,39 @@ +
+ + +
+ {{lang_name}} * + +
+
+

{{lang_configurationChoose}}

+ {{#groups}} +
+
{{group}}
+
+ {{#modules}} +
+ + {{#unique}} + + {{/unique}} + {{^unique}} + + {{/unique}} + + + {{#missing}} + + {{/missing}} +
+ {{/modules}} + {{^modules}} +
{{lang_noModuleOfType}}
+ {{/modules}} +
+
+ {{/groups}} +
+ +
+
diff --git a/modules/sysconfig/templates/config-module-list.html b/modules/sysconfig/templates/config-module-list.html new file mode 100644 index 00000000..6cd77f9e --- /dev/null +++ b/modules/sysconfig/templates/config-module-list.html @@ -0,0 +1,17 @@ +
+ + + + {{#modules}} + + + + + {{/modules}} +
{{module}} + +
+ {{^modules}} +
{{lang_noContent}}
+ {{/modules}} +
\ No newline at end of file diff --git a/modules/sysconfig/templates/custom-filelist.html b/modules/sysconfig/templates/custom-filelist.html new file mode 100644 index 00000000..3ad241dd --- /dev/null +++ b/modules/sysconfig/templates/custom-filelist.html @@ -0,0 +1,16 @@ + + + +{{#files}} + + {{#isdir}} + + {{/isdir}} + {{^isdir}} + + + {{/isdir}} + + {{/files}} +
{{name}}{{name}}{{size}}
+{{lang_back}} « diff --git a/modules/sysconfig/templates/custom-fileselect.html b/modules/sysconfig/templates/custom-fileselect.html new file mode 100644 index 00000000..000c8d10 --- /dev/null +++ b/modules/sysconfig/templates/custom-fileselect.html @@ -0,0 +1,31 @@ +
+ + + +
+ {{lang_moduleName}} + +
+
+ +
+
+
+

{{lang_checkFileContent}}

+ + {{#files}} + + {{#isdir}} + + {{/isdir}} + {{^isdir}} + + + {{/isdir}} + + {{/files}} +
{{name}}{{name}}{{size}}
+
+ +
+
diff --git a/modules/sysconfig/templates/custom-upload.html b/modules/sysconfig/templates/custom-upload.html new file mode 100644 index 00000000..c453a97d --- /dev/null +++ b/modules/sysconfig/templates/custom-upload.html @@ -0,0 +1,18 @@ +

{{lang_customModuleInfo1}}

+ +

{{lang_customModuleInfo2}}

+ +
+ + +
+ + + + {{lang_browseForFile}}… + + +
+

{{lang_supportedFiles}}: .tar.gz, .tar.bz2, .zip

+ +
diff --git a/modules/sysconfig/templates/ldap-finish.html b/modules/sysconfig/templates/ldap-finish.html new file mode 100644 index 00000000..a735e792 --- /dev/null +++ b/modules/sysconfig/templates/ldap-finish.html @@ -0,0 +1,29 @@ +

+ {{lang_ldapStarted}} +

+ +
+
{{lang_generateModule}}
+
+
+ + + diff --git a/modules/sysconfig/templates/ldap-start.html b/modules/sysconfig/templates/ldap-start.html new file mode 100644 index 00000000..7892b63f --- /dev/null +++ b/modules/sysconfig/templates/ldap-start.html @@ -0,0 +1,101 @@ +

+ {{lang_ldapText1}} +
+ {{lang_ldapText2}} +

+ +
+ + + + +
+ {{lang_moduleTitle}} + +
+
+ Server * + + +
+
+ {{lang_bindDN}} + + +
+
+ {{lang_password}} + + +
+
+ {{lang_searchBase}} * + + +
+
+
+ Home + + + + +
+
+
+ +
+ {{lang_sslDescription}} +
+
+ +
+
+
+
+
+ {{lang_customCertificate}} +
+-----BEGIN CERTIFICATE-----
+MIIFfTCCA...
+.....
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+.....
+-----END CERTIFICATE-----
+ +
+
+ +
+
+
+
+ + diff --git a/modules/sysconfig/templates/sshconfig-start.html b/modules/sysconfig/templates/sshconfig-start.html new file mode 100644 index 00000000..2aa409d3 --- /dev/null +++ b/modules/sysconfig/templates/sshconfig-start.html @@ -0,0 +1,27 @@ +
+ + +
+ {{lang_moduleName}} + +
+
+ +

{{lang_allowPassInfo}}

+
+
+ + + {{lang_rootKeyInfo}} +
+
+ + + {{lang_listenPortInfo}} +
+ +
+ diff --git a/modules/sysconfig/templates/start.html b/modules/sysconfig/templates/start.html new file mode 100644 index 00000000..f55a5501 --- /dev/null +++ b/modules/sysconfig/templates/start.html @@ -0,0 +1,12 @@ +

{{lang_moduleChoose}}

+ +{{#modules}} +
+
+ {{title}} {{lang_add}} +
+
+ {{description}} +
+
+{{/modules}} diff --git a/modules/sysconfignew/config.json b/modules/sysconfignew/config.json new file mode 100644 index 00000000..d5da4cc8 --- /dev/null +++ b/modules/sysconfignew/config.json @@ -0,0 +1,4 @@ +{ + "category":"hidden", + "enabled":"true" +} diff --git a/modules/sysconfignew/module.inc.php b/modules/sysconfignew/module.inc.php new file mode 100644 index 00000000..105ad6c7 --- /dev/null +++ b/modules/sysconfignew/module.inc.php @@ -0,0 +1,113 @@ +tmconfigs = $this->tmpath . '/configs'; + $this->tmmodules = $this->tmpath . '/modules'; + } + + + protected function doRender(){ + $module = $_GET['module']; + if(isset($module)){ + Render::addTemplate('module-editor',array( + "module" => $module + )); + }else{ + if(is_dir($this->tmpath)){ + $configs = array(); + $modules = array(); + + foreach($this->listDirectory($this->tmconfigs) as $key => $value) + $configs[] = array( + "name" => $value + ); + + foreach($this->listDirectory($this->tmmodules) as $key => $value) + $modules[] = array( + "name" => $value + ); + + $data = array( + "configs" => $configs, + "modules" => $modules + ); + Render::addTemplate('_pagenew',$data); + }else{ + Message::addError('no-tm-scripts'); + } + } + } + + protected function doAjax(){ + $request = $_GET['request']; + switch($request){ + case "module-contents": + $path = $this->tmpath . '/modules/' . Request::get('module'); + $data = $this->getDirContents($path); + $json = json_encode($data); + print_r($json); + break; + case "configs": + $this->tmconfigs = $this->tmpath . '/configs'; + $this->tmmodules = $this->tmpath . '/modules'; + $userModules = $this->listDirectory($this->tmconfigs . '/' . Request::get('config')); + $modules = array(); + foreach($this->listDirectory($this->tmmodules) as $key => $value){ + $chosen = (in_array($value, $userModules)) ? true : false; + $modules[] = array( + "name" => $value, + "chosen" => $chosen + ); + } + + foreach ($modules as $module) { + $class = ($module['chosen']) ? "select-item select-item-selected" : "select-item"; + $ret .= ""; + } + + echo $ret; + break; + } + + } + + private function getDirContents($path){ + $ret = array(); + foreach ($this->listDirectory($path) as $key => $value) { + if(is_dir($path . "/" . $value)){ + $ret["dir_" . $value] = $this->getDirContents($path . "/" . $value); + }else{ + if(is_link($path . "/" . $value)){ + $ret["link_" . $value] = readlink($path . "/" . $value); + }else{ + if(mime_content_type($path . "/" . $value) == "text/plain"){ + $ret["file_" . $value] = file_get_contents($path . "/" . $value); + }else{ + $ret["lock_" . $value] = " oops"; + } + } + } + } + return $ret; + } + + private function listDirectory($path){ + return array_diff(scandir($path), array('..', '.')); + } + +} diff --git a/modules/sysconfignew/templates/_pagenew.html b/modules/sysconfignew/templates/_pagenew.html new file mode 100644 index 00000000..98881ae3 --- /dev/null +++ b/modules/sysconfignew/templates/_pagenew.html @@ -0,0 +1,190 @@ +
+
+
+
+
{{lang_configurations}}
+
+
+ {{lang_configsDescription}} +
+ + + + + + + + {{#configs}} + + + + + + {{/configs}} + +
{{lang_configName}}
{{name}} + + + +
+ +
+
+
+
+
+
{{lang_modules}}
+
+
+ {{lang_modulesDescription}} +
+ + + + + + + + {{#modules}} + + + + + + {{/modules}} + +
{{lang_configName}}
{{name}} + + + +
+ +
+
+
+ + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/modules/sysconfignew/templates/module-editor.html b/modules/sysconfignew/templates/module-editor.html new file mode 100644 index 00000000..3ea28bf8 --- /dev/null +++ b/modules/sysconfignew/templates/module-editor.html @@ -0,0 +1,269 @@ + +
+
+ {{lang_back}} +
+
+ {{module}} +
+
+
+ +
+ + +
+ +
+
+
+ + + + + \ No newline at end of file diff --git a/modules/syslog.inc.php b/modules/syslog.inc.php deleted file mode 100644 index 43a9bd28..00000000 --- a/modules/syslog.inc.php +++ /dev/null @@ -1,94 +0,0 @@ -exec(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $day = date('d.m.Y', $row['dateline']); - if ($day === $today) { - $day = Dictionary::translate('today'); - } elseif ($day === $yesterday) { - $day = Dictionary::translate('yesterday'); - } - $row['date'] = $day . date(' H:i', $row['dateline']); - $row['icon'] = $this->eventToIconName($row['logtypeid']); - $lines[] = $row; - } - - $paginate->render('page-syslog', array( - 'filter' => $filter, - 'not' => $not, - 'list' => $lines - )); - } - - private function eventToIconName($event) - { - switch ($event) { - case 'session-open': - return 'glyphicon-log-in'; - case 'session-close': - return 'glyphicon-log-out'; - case 'partition-swap': - return 'glyphicon-info-sign'; - case 'partition-temp': - case 'smartctl-realloc': - return 'glyphicon-exclamation-sign'; - default: - return 'glyphicon-minus'; - } - } - -} diff --git a/modules/syslog/config.json b/modules/syslog/config.json new file mode 100644 index 00000000..d42dc3e3 --- /dev/null +++ b/modules/syslog/config.json @@ -0,0 +1,4 @@ +{ + "category":"status", + "enabled":"true" +} diff --git a/modules/syslog/module.inc.php b/modules/syslog/module.inc.php new file mode 100644 index 00000000..43a9bd28 --- /dev/null +++ b/modules/syslog/module.inc.php @@ -0,0 +1,94 @@ +exec(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $day = date('d.m.Y', $row['dateline']); + if ($day === $today) { + $day = Dictionary::translate('today'); + } elseif ($day === $yesterday) { + $day = Dictionary::translate('yesterday'); + } + $row['date'] = $day . date(' H:i', $row['dateline']); + $row['icon'] = $this->eventToIconName($row['logtypeid']); + $lines[] = $row; + } + + $paginate->render('page-syslog', array( + 'filter' => $filter, + 'not' => $not, + 'list' => $lines + )); + } + + private function eventToIconName($event) + { + switch ($event) { + case 'session-open': + return 'glyphicon-log-in'; + case 'session-close': + return 'glyphicon-log-out'; + case 'partition-swap': + return 'glyphicon-info-sign'; + case 'partition-temp': + case 'smartctl-realloc': + return 'glyphicon-exclamation-sign'; + default: + return 'glyphicon-minus'; + } + } + +} diff --git a/modules/syslog/templates/page-syslog.html b/modules/syslog/templates/page-syslog.html new file mode 100644 index 00000000..98e94291 --- /dev/null +++ b/modules/syslog/templates/page-syslog.html @@ -0,0 +1,58 @@ +

{{lang_clientLog}}

+
+ +
+ {{lang_filter}} + + + {{lang_not}} + + + + +
+
+{{{pagenav}}} + + + + + + + + + + {{#list}} + + + + + + + + {{/list}} + +
{{lang_when}}{{lang_client}}{{lang_event}}{{lang_details}}
{{date}}{{clientip}}{{description}}{{#extra}} + » + + {{/extra}}
+{{{pagenav}}} + + + + diff --git a/modules/systemstatus.inc.php b/modules/systemstatus.inc.php deleted file mode 100644 index 105202ac..00000000 --- a/modules/systemstatus.inc.php +++ /dev/null @@ -1,361 +0,0 @@ -rebootTask = Taskmanager::submit('Reboot'); - } - } - - protected function doRender() - { - $data = array(); - if (is_array($this->rebootTask) && isset($this->rebootTask['id'])) { - $data['rebootTask'] = $this->rebootTask['id']; - } - Render::addScriptTop('custom'); - Render::addScriptBottom('circles.min'); - Render::addTemplate('systemstatus/_page', $data); - } - - protected function doAjax() - { - User::load(); - - if (!User::isLoggedIn()) - return; - - $action = 'ajax' . Request::any('action'); - if (method_exists($this, $action)) { - $this->$action(); - Message::renderList(); - } else { - echo "Action $action not known in " . get_class(); - } - } - - protected function ajaxDmsdUsers() - { - $ret = Download::asStringPost('http://127.0.0.1:9080/status/fileserver', false, 2, $code); - if ($code != 200) { - Header('HTTP/1.1 502 Internal Server Error'); - die('Internal Server Wurst'); - } - $data = @json_decode($ret, true); - if (is_array($data)) { - $ret = 'Uploads: ' . $data['activeUploads'] . ', Downloads: ' . $data['activeDownloads']; - } else { - $ret = '???'; - } - die($ret); - } - - protected function ajaxDiskStat() - { - $task = Taskmanager::submit('DiskStat'); - if ($task === false) - return; - $task = Taskmanager::waitComplete($task, 3000); - - if (!isset($task['data']['list']) || empty($task['data']['list'])) { - Taskmanager::addErrorMessage($task); - return; - } - $store = Property::getVmStoreUrl(); - $storeUsage = false; - $systemUsage = false; - if ($store !== false) { - if ($store === '') - $storePoint = '/'; - else - $storePoint = CONFIG_VMSTORE_DIR; - // Determine free space - foreach ($task['data']['list'] as $entry) { - if ($entry['mountPoint'] === $storePoint) { - $storeUsage = array( - 'percent' => $entry['usedPercent'], - 'size' => Util::readableFileSize($entry['sizeKb'] * 1024), - 'free' => Util::readableFileSize($entry['freeKb'] * 1024), - 'color' => $this->usageColor($entry['usedPercent']) - ); - } - if ($entry['mountPoint'] === '/') { - $systemUsage = array( - 'percent' => $entry['usedPercent'], - 'size' => Util::readableFileSize($entry['sizeKb'] * 1024), - 'free' => Util::readableFileSize($entry['freeKb'] * 1024), - 'color' => $this->usageColor($entry['usedPercent']) - ); - } - } - $data = array( - 'store' => $storeUsage, - 'system' => $systemUsage - ); - // Determine if proper vm store is being used - if ($store !== '') { - $data['storeMissing'] = $store; - } - foreach ($task['data']['list'] as $entry) { - if ($entry['mountPoint'] !== CONFIG_VMSTORE_DIR) - continue; - if ($store !== $entry['fileSystem']) { - $data['wrongStore'] = $entry['fileSystem']; - break; - } - $data['storeMissing'] = false; - } - } else { - $data['notConfigured'] = true; - } - echo Render::parse('systemstatus/diskstat', $data); - } - - protected function ajaxAddressList() - { - $task = Taskmanager::submit('LocalAddressesList'); - if ($task === false) - return; - $task = Taskmanager::waitComplete($task, 3000); - - if (!isset($task['data']['addresses']) || empty($task['data']['addresses'])) { - Taskmanager::addErrorMessage($task); - return; - } - - $sort = array(); - $primary = Property::getServerIp(); - foreach ($task['data']['addresses'] as &$addr) { - $sort[] = $addr['type'] . $addr['ip']; - if ($addr['ip'] === $primary) - $addr['primary'] = true; - } - array_multisort($sort, SORT_STRING, $task['data']['addresses']); - echo Render::parse('systemstatus/addresses', array( - 'addresses' => $task['data']['addresses'] - )); - } - - private function sysInfo() - { - $data = array(); - $memInfo = file_get_contents('/proc/meminfo'); - $stat = file_get_contents('/proc/stat'); - preg_match_all('/\b(\w+):\s+(\d+)\s/s', $memInfo, $out, PREG_SET_ORDER); - foreach ($out as $e) { - $data[$e[1]] = $e[2]; - } - if (preg_match('/\bcpu\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)(\s|$)/', $stat, $out)) { - $data['CpuTotal'] = $out['user'] + $out['nice'] + $out['system'] + $out['idle'] + $out['iowait'] + $out['irq'] + $out['softirq']; - $data['CpuIdle'] = $out['idle'] + $out['iowait']; - $data['CpuSystem'] = $out['irq'] + $out['softirq']; - } - return $data; - } - - protected function ajaxSystemInfo() - { - $cpuInfo = file_get_contents('/proc/cpuinfo'); - $uptime = file_get_contents('/proc/uptime'); - $cpuCount = preg_match_all('/\bprocessor\s/', $cpuInfo, $out); - //$cpuCount = count($out); - $data = array( - 'cpuCount' => $cpuCount, - 'memTotal' => '???', - 'memFree' => '???', - 'swapTotal' => '???', - 'swapUsed' => '???', - 'uptime' => '???' - ); - if (preg_match('/^(\d+)\D/', $uptime, $out)) { - $data['uptime'] = floor($out[1] / 86400) . ' ' . Dictionary::translate('lang_days') . ', ' . floor(($out[1] % 86400) / 3600) . ' ' . Dictionary::translate('lang_hours'); // TODO: i18n - } - $info = $this->sysInfo(); - if (isset($info['MemTotal']) && isset($info['MemFree']) && isset($info['SwapTotal'])) { - $data['memTotal'] = Util::readableFileSize($info['MemTotal'] * 1024); - $data['memFree'] = Util::readableFileSize(($info['MemFree'] + $info['Buffers'] + $info['Cached']) * 1024); - $data['memPercent'] = 100 - round((($info['MemFree'] + $info['Buffers'] + $info['Cached']) / $info['MemTotal']) * 100); - $data['swapTotal'] = Util::readableFileSize($info['SwapTotal'] * 1024); - $data['swapUsed'] = Util::readableFileSize(($info['SwapTotal'] - $info['SwapFree']) * 1024); - $data['swapPercent'] = 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100); - $data['swapWarning'] = ($data['swapPercent'] > 50 || ($info['SwapTotal'] - $info['SwapFree']) > 200000); - } - if (isset($info['CpuIdle']) && isset($info['CpuSystem']) && isset($info['CpuTotal'])) { - $data['cpuLoad'] = 100 - round(($info['CpuIdle'] / $info['CpuTotal']) * 100); - $data['cpuSystem'] = round(($info['CpuSystem'] / $info['CpuTotal']) * 100); - $data['cpuLoadOk'] = true; - $data['CpuTotal'] = $info['CpuTotal']; - $data['CpuIdle'] = $info['CpuIdle']; - } - echo Render::parse('systemstatus/systeminfo', $data); - } - - protected function ajaxSysPoll() - { - $info = $this->sysInfo(); - $data = array( - 'CpuTotal' => $info['CpuTotal'], - 'CpuIdle' => $info['CpuIdle'], - 'MemPercent' => 100 - round((($info['MemFree'] + $info['Buffers'] + $info['Cached']) / $info['MemTotal']) * 100), - 'SwapPercent' => 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100) - ); - Header('Content-Type: application/json; charset=utf-8'); - die(json_encode($data)); - } - - protected function ajaxServices() - { - $data = array(); - - $taskId = Trigger::ldadp(); - if ($taskId === false) - return; - $status = Taskmanager::waitComplete($taskId, 10000); - - if (Taskmanager::isFailed($status)) { - if (isset($status['data']['messages'])) - $data['ldadpError'] = $status['data']['messages']; - else - $data['ldadpError'] = 'Taskmanager error'; - } - // TODO: Dozentenmodul, tftp, ... - - echo Render::parse('systemstatus/services', $data); - } - - protected function ajaxDmsdLog() - { - $fh = @fopen('/var/log/dmsd.log', 'r'); - if ($fh === false) { - echo 'Error opening log file'; - return; - } - fseek($fh, -6000, SEEK_END); - $data = fread($fh, 6000); - @fclose($fh); - if ($data === false) { - echo 'Error reading from log file'; - return; - } - // If we could read less, try the .1 file too - $amount = 6000 - strlen($data); - if ($amount > 100) { - $fh = @fopen('/var/log/dmsd.log.1', 'r'); - if ($fh !== false) { - fseek($fh, -$amount, SEEK_END); - $data = fread($fh, $amount) . $data; - @fclose($fh); - } - } - if (strlen($data) < 5990) { - $start = 0; - } else { - $start = strpos($data, "\n") + 1; - } - echo '
', htmlspecialchars(substr($data, $start)), '
'; - } - - protected function ajaxLdadpLog() - { - $files = glob('/var/log/ldadp/*.log', GLOB_NOSORT); - if ($files === false || empty($files)) echo('No logs found'); - $now = time(); - foreach ($files as $file) { - $mod = filemtime($file); - if ($now - $mod > 86400) continue; - // New enough - handle - preg_match(',/(\d+)\.log,', $file, $out); - $module = ConfigModule::get($out[1]); - if ($module === false) { - echo '

Module ', $out[1], '

'; - } else { - echo '

Module ', htmlspecialchars($module->title()), '

'; - } - $fh = @fopen($file, 'r'); - if ($fh === false) { - echo '
Error opening log file
'; - continue; - } - fseek($fh, -5000, SEEK_END); - $data = fread($fh, 5000); - @fclose($fh); - if ($data === false) { - echo '
Error reading from log file
'; - continue; - } - if (strlen($data) < 4990) { - $start = 0; - } else { - $start = strpos($data, "\n") + 1; - } - echo '
', htmlspecialchars(substr($data, $start)), '
'; - } - } - - protected function ajaxNetstat() - { - $taskId = Taskmanager::submit('Netstat'); - if ($taskId === false) - return; - $status = Taskmanager::waitComplete($taskId, 3500); - - if (isset($status['data']['messages'])) - $data = $status['data']['messages']; - else - $data = 'Taskmanager error'; - - echo '
', htmlspecialchars($data), '
'; - } - - protected function ajaxPsList() - { - $taskId = Taskmanager::submit('PsList'); - if ($taskId === false) - return; - $status = Taskmanager::waitComplete($taskId, 3500); - - if (isset($status['data']['messages'])) - $data = $status['data']['messages']; - else - $data = 'Taskmanager error'; - - echo '
', htmlspecialchars($data), '
'; - } - - private function usageColor($percent) - { - if ($percent <= 50) { - $r = $b = $percent / 3; - $g = (100 - $percent * (50 / 80)); - } elseif ($percent <= 70) { - $r = 55 + ($percent - 50) * (30 / 20); - $g = 60; - $b = 0; - } else { - $r = ($percent - 70) / 3 + 90; - $g = (100 - $percent) * (60 / 30); - $b = 0; - } - $r = dechex(round($r * 2.55)); - $g = dechex(round($g * 2.55)); - $b = dechex(round($b * 2.55)); - return sprintf("%02s%02s%02s", $r, $g, $b); - } - -} diff --git a/modules/systemstatus/config.json b/modules/systemstatus/config.json new file mode 100644 index 00000000..d42dc3e3 --- /dev/null +++ b/modules/systemstatus/config.json @@ -0,0 +1,4 @@ +{ + "category":"status", + "enabled":"true" +} diff --git a/modules/systemstatus/module.inc.php b/modules/systemstatus/module.inc.php new file mode 100644 index 00000000..2a5382e1 --- /dev/null +++ b/modules/systemstatus/module.inc.php @@ -0,0 +1,361 @@ +rebootTask = Taskmanager::submit('Reboot'); + } + } + + protected function doRender() + { + $data = array(); + if (is_array($this->rebootTask) && isset($this->rebootTask['id'])) { + $data['rebootTask'] = $this->rebootTask['id']; + } + Render::addScriptTop('custom'); + Render::addScriptBottom('circles.min'); + Render::addTemplate('_page', $data); + } + + protected function doAjax() + { + User::load(); + + if (!User::isLoggedIn()) + return; + + $action = 'ajax' . Request::any('action'); + if (method_exists($this, $action)) { + $this->$action(); + Message::renderList(); + } else { + echo "Action $action not known in " . get_class(); + } + } + + protected function ajaxDmsdUsers() + { + $ret = Download::asStringPost('http://127.0.0.1:9080/status/fileserver', false, 2, $code); + if ($code != 200) { + Header('HTTP/1.1 502 Internal Server Error'); + die('Internal Server Wurst'); + } + $data = @json_decode($ret, true); + if (is_array($data)) { + $ret = 'Uploads: ' . $data['activeUploads'] . ', Downloads: ' . $data['activeDownloads']; + } else { + $ret = '???'; + } + die($ret); + } + + protected function ajaxDiskStat() + { + $task = Taskmanager::submit('DiskStat'); + if ($task === false) + return; + $task = Taskmanager::waitComplete($task, 3000); + + if (!isset($task['data']['list']) || empty($task['data']['list'])) { + Taskmanager::addErrorMessage($task); + return; + } + $store = Property::getVmStoreUrl(); + $storeUsage = false; + $systemUsage = false; + if ($store !== false) { + if ($store === '') + $storePoint = '/'; + else + $storePoint = CONFIG_VMSTORE_DIR; + // Determine free space + foreach ($task['data']['list'] as $entry) { + if ($entry['mountPoint'] === $storePoint) { + $storeUsage = array( + 'percent' => $entry['usedPercent'], + 'size' => Util::readableFileSize($entry['sizeKb'] * 1024), + 'free' => Util::readableFileSize($entry['freeKb'] * 1024), + 'color' => $this->usageColor($entry['usedPercent']) + ); + } + if ($entry['mountPoint'] === '/') { + $systemUsage = array( + 'percent' => $entry['usedPercent'], + 'size' => Util::readableFileSize($entry['sizeKb'] * 1024), + 'free' => Util::readableFileSize($entry['freeKb'] * 1024), + 'color' => $this->usageColor($entry['usedPercent']) + ); + } + } + $data = array( + 'store' => $storeUsage, + 'system' => $systemUsage + ); + // Determine if proper vm store is being used + if ($store !== '') { + $data['storeMissing'] = $store; + } + foreach ($task['data']['list'] as $entry) { + if ($entry['mountPoint'] !== CONFIG_VMSTORE_DIR) + continue; + if ($store !== $entry['fileSystem']) { + $data['wrongStore'] = $entry['fileSystem']; + break; + } + $data['storeMissing'] = false; + } + } else { + $data['notConfigured'] = true; + } + echo Render::parse('diskstat', $data); + } + + protected function ajaxAddressList() + { + $task = Taskmanager::submit('LocalAddressesList'); + if ($task === false) + return; + $task = Taskmanager::waitComplete($task, 3000); + + if (!isset($task['data']['addresses']) || empty($task['data']['addresses'])) { + Taskmanager::addErrorMessage($task); + return; + } + + $sort = array(); + $primary = Property::getServerIp(); + foreach ($task['data']['addresses'] as &$addr) { + $sort[] = $addr['type'] . $addr['ip']; + if ($addr['ip'] === $primary) + $addr['primary'] = true; + } + array_multisort($sort, SORT_STRING, $task['data']['addresses']); + echo Render::parse('addresses', array( + 'addresses' => $task['data']['addresses'] + )); + } + + private function sysInfo() + { + $data = array(); + $memInfo = file_get_contents('/proc/meminfo'); + $stat = file_get_contents('/proc/stat'); + preg_match_all('/\b(\w+):\s+(\d+)\s/s', $memInfo, $out, PREG_SET_ORDER); + foreach ($out as $e) { + $data[$e[1]] = $e[2]; + } + if (preg_match('/\bcpu\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)(\s|$)/', $stat, $out)) { + $data['CpuTotal'] = $out['user'] + $out['nice'] + $out['system'] + $out['idle'] + $out['iowait'] + $out['irq'] + $out['softirq']; + $data['CpuIdle'] = $out['idle'] + $out['iowait']; + $data['CpuSystem'] = $out['irq'] + $out['softirq']; + } + return $data; + } + + protected function ajaxSystemInfo() + { + $cpuInfo = file_get_contents('/proc/cpuinfo'); + $uptime = file_get_contents('/proc/uptime'); + $cpuCount = preg_match_all('/\bprocessor\s/', $cpuInfo, $out); + //$cpuCount = count($out); + $data = array( + 'cpuCount' => $cpuCount, + 'memTotal' => '???', + 'memFree' => '???', + 'swapTotal' => '???', + 'swapUsed' => '???', + 'uptime' => '???' + ); + if (preg_match('/^(\d+)\D/', $uptime, $out)) { + $data['uptime'] = floor($out[1] / 86400) . ' ' . Dictionary::translate('lang_days') . ', ' . floor(($out[1] % 86400) / 3600) . ' ' . Dictionary::translate('lang_hours'); // TODO: i18n + } + $info = $this->sysInfo(); + if (isset($info['MemTotal']) && isset($info['MemFree']) && isset($info['SwapTotal'])) { + $data['memTotal'] = Util::readableFileSize($info['MemTotal'] * 1024); + $data['memFree'] = Util::readableFileSize(($info['MemFree'] + $info['Buffers'] + $info['Cached']) * 1024); + $data['memPercent'] = 100 - round((($info['MemFree'] + $info['Buffers'] + $info['Cached']) / $info['MemTotal']) * 100); + $data['swapTotal'] = Util::readableFileSize($info['SwapTotal'] * 1024); + $data['swapUsed'] = Util::readableFileSize(($info['SwapTotal'] - $info['SwapFree']) * 1024); + $data['swapPercent'] = 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100); + $data['swapWarning'] = ($data['swapPercent'] > 50 || ($info['SwapTotal'] - $info['SwapFree']) > 200000); + } + if (isset($info['CpuIdle']) && isset($info['CpuSystem']) && isset($info['CpuTotal'])) { + $data['cpuLoad'] = 100 - round(($info['CpuIdle'] / $info['CpuTotal']) * 100); + $data['cpuSystem'] = round(($info['CpuSystem'] / $info['CpuTotal']) * 100); + $data['cpuLoadOk'] = true; + $data['CpuTotal'] = $info['CpuTotal']; + $data['CpuIdle'] = $info['CpuIdle']; + } + echo Render::parse('systeminfo', $data); + } + + protected function ajaxSysPoll() + { + $info = $this->sysInfo(); + $data = array( + 'CpuTotal' => $info['CpuTotal'], + 'CpuIdle' => $info['CpuIdle'], + 'MemPercent' => 100 - round((($info['MemFree'] + $info['Buffers'] + $info['Cached']) / $info['MemTotal']) * 100), + 'SwapPercent' => 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100) + ); + Header('Content-Type: application/json; charset=utf-8'); + die(json_encode($data)); + } + + protected function ajaxServices() + { + $data = array(); + + $taskId = Trigger::ldadp(); + if ($taskId === false) + return; + $status = Taskmanager::waitComplete($taskId, 10000); + + if (Taskmanager::isFailed($status)) { + if (isset($status['data']['messages'])) + $data['ldadpError'] = $status['data']['messages']; + else + $data['ldadpError'] = 'Taskmanager error'; + } + // TODO: Dozentenmodul, tftp, ... + + echo Render::parse('services', $data); + } + + protected function ajaxDmsdLog() + { + $fh = @fopen('/var/log/dmsd.log', 'r'); + if ($fh === false) { + echo 'Error opening log file'; + return; + } + fseek($fh, -6000, SEEK_END); + $data = fread($fh, 6000); + @fclose($fh); + if ($data === false) { + echo 'Error reading from log file'; + return; + } + // If we could read less, try the .1 file too + $amount = 6000 - strlen($data); + if ($amount > 100) { + $fh = @fopen('/var/log/dmsd.log.1', 'r'); + if ($fh !== false) { + fseek($fh, -$amount, SEEK_END); + $data = fread($fh, $amount) . $data; + @fclose($fh); + } + } + if (strlen($data) < 5990) { + $start = 0; + } else { + $start = strpos($data, "\n") + 1; + } + echo '
', htmlspecialchars(substr($data, $start)), '
'; + } + + protected function ajaxLdadpLog() + { + $files = glob('/var/log/ldadp/*.log', GLOB_NOSORT); + if ($files === false || empty($files)) echo('No logs found'); + $now = time(); + foreach ($files as $file) { + $mod = filemtime($file); + if ($now - $mod > 86400) continue; + // New enough - handle + preg_match(',/(\d+)\.log,', $file, $out); + $module = ConfigModule::get($out[1]); + if ($module === false) { + echo '

Module ', $out[1], '

'; + } else { + echo '

Module ', htmlspecialchars($module->title()), '

'; + } + $fh = @fopen($file, 'r'); + if ($fh === false) { + echo '
Error opening log file
'; + continue; + } + fseek($fh, -5000, SEEK_END); + $data = fread($fh, 5000); + @fclose($fh); + if ($data === false) { + echo '
Error reading from log file
'; + continue; + } + if (strlen($data) < 4990) { + $start = 0; + } else { + $start = strpos($data, "\n") + 1; + } + echo '
', htmlspecialchars(substr($data, $start)), '
'; + } + } + + protected function ajaxNetstat() + { + $taskId = Taskmanager::submit('Netstat'); + if ($taskId === false) + return; + $status = Taskmanager::waitComplete($taskId, 3500); + + if (isset($status['data']['messages'])) + $data = $status['data']['messages']; + else + $data = 'Taskmanager error'; + + echo '
', htmlspecialchars($data), '
'; + } + + protected function ajaxPsList() + { + $taskId = Taskmanager::submit('PsList'); + if ($taskId === false) + return; + $status = Taskmanager::waitComplete($taskId, 3500); + + if (isset($status['data']['messages'])) + $data = $status['data']['messages']; + else + $data = 'Taskmanager error'; + + echo '
', htmlspecialchars($data), '
'; + } + + private function usageColor($percent) + { + if ($percent <= 50) { + $r = $b = $percent / 3; + $g = (100 - $percent * (50 / 80)); + } elseif ($percent <= 70) { + $r = 55 + ($percent - 50) * (30 / 20); + $g = 60; + $b = 0; + } else { + $r = ($percent - 70) / 3 + 90; + $g = (100 - $percent) * (60 / 30); + $b = 0; + } + $r = dechex(round($r * 2.55)); + $g = dechex(round($g * 2.55)); + $b = dechex(round($b * 2.55)); + return sprintf("%02s%02s%02s", $r, $g, $b); + } + +} diff --git a/modules/systemstatus/templates/_page.html b/modules/systemstatus/templates/_page.html new file mode 100644 index 00000000..51aa5b55 --- /dev/null +++ b/modules/systemstatus/templates/_page.html @@ -0,0 +1,129 @@ +{{#rebootTask}} +
Reboot...
+{{/rebootTask}} + +
+ +
+
+
+ {{lang_space}} +
+
+ +
+
+
+ +
+
+
+ {{lang_services}} +
+
+ +
+
+
+ +
+ + +
+ +
+
+
+ {{lang_addressConfiguration}} +
+
+ +
+
+
+ +
+
+
+ {{lang_system}} +
+
+ +
+
+
+ +
+ +
+ +
+
+
+ {{lang_maintenance}} +
+
+
+ + +
Server Reboot
+ + +
+
+
+
+
+ +
+ +

{{lang_advanced}}

+ +
+
+ {{lang_dmsdLog}} +
+
+ +
+
+
+
+ {{lang_ldadpLog}} +
+
+ +
+
+
+
+ netstat -tulpn +
+
+ +
+
+
+
+ ps auxf +
+
+ +
+
+ + diff --git a/modules/systemstatus/templates/addresses.html b/modules/systemstatus/templates/addresses.html new file mode 100644 index 00000000..ce92c4d5 --- /dev/null +++ b/modules/systemstatus/templates/addresses.html @@ -0,0 +1,8 @@ + + {{#addresses}} + + + + + {{/addresses}} +
{{ip}}({{iface}})
\ No newline at end of file diff --git a/modules/systemstatus/templates/diskstat.html b/modules/systemstatus/templates/diskstat.html new file mode 100644 index 00000000..528d9792 --- /dev/null +++ b/modules/systemstatus/templates/diskstat.html @@ -0,0 +1,63 @@ +
+ {{#system}} + {{lang_systemPartition}} +
+
{{lang_capacity}}: {{size}}
+
{{lang_free}}: {{free}}
+ {{/system}} + {{^system}} + {{lang_systemStoreError}} + {{/system}} +
+
+ {{#store}} + {{lang_vmStore}} +
+
{{lang_capacity}}: {{size}}
+
{{lang_free}}: {{free}}
+ {{/store}} + {{^store}} + {{lang_vmStoreError}} + {{/store}} +
+
+{{#notConfigured}} +
{{lang_storeNotConfigured}}
+{{/notConfigured}} +{{#storeMissing}} +
{{lang_storeMissingExpected}} {{storeMissing}}
+{{/storeMissing}} +{{#wrongStore}} +
{{lang_foundStore}} {{wrongStore}}
+{{/wrongStore}} +{{lang_goToStoreConf}} + diff --git a/modules/systemstatus/templates/services.html b/modules/systemstatus/templates/services.html new file mode 100644 index 00000000..6c4f0b93 --- /dev/null +++ b/modules/systemstatus/templates/services.html @@ -0,0 +1,6 @@ +{{#ldadpError}} +
{{ldadpError}}
+{{/ldadpError}} +{{^ldadpError}} +
LDAP-AD-Proxy: OK
+{{/ldadpError}} diff --git a/modules/systemstatus/templates/systeminfo.html b/modules/systemstatus/templates/systeminfo.html new file mode 100644 index 00000000..ed4a1532 --- /dev/null +++ b/modules/systemstatus/templates/systeminfo.html @@ -0,0 +1,115 @@ +
+ {{lang_uptimeOS}}: {{uptime}} +
+ +
+ {{lang_cpuLoad}} + {{#cpuLoadOk}} +
+
{{lang_average}}: {{cpuLoad}}%
+
{{lang_onlyOS}}: {{cpuSystem}}%
+
{{lang_logicCPUs}}: {{cpuCount}}
+ {{/cpuLoadOk}} + {{^cpuLoadOk}} + {{lang_notDetermined}} + {{/cpuLoadOk}} +
+ +
+ {{lang_ramUsage}} + {{#memTotal}} +
+
{{lang_total}}: {{memTotal}}
+
{{lang_free}}: {{memFree}}
+ {{/memTotal}} + {{^memTotal}} + {{lang_notDetermined}} + {{/memTotal}} +
+ +
+ {{lang_swapUsage}} + {{#memTotal}} +
+
{{lang_total}}: {{swapTotal}}
+
{{lang_occupied}}: {{swapUsed}}
+ {{/memTotal}} + {{^memTotal}} + {{lang_notDetermined}} + {{/memTotal}} +
+ +
+ +{{#swapWarning}} +
+ {{lang_attention}} {{lang_swapWarning}} +
+{{/swapWarning}} + + diff --git a/modules/translation.inc.php b/modules/translation.inc.php deleted file mode 100644 index 5b8b452a..00000000 --- a/modules/translation.inc.php +++ /dev/null @@ -1,491 +0,0 @@ -updateJson(); - Util::redirect('?do=Translation'); - } - if (Request::post('delete')) { - $this->deleteTag(Request::post('path'), Request::post('delete')); - Util::redirect('?do=Translation'); // TODO: Ajax post for delete so we stay on the page - } - - $this->template = Request::get('template'); - $this->page = Request::get('page'); - } - - protected function doRender() - { - $langs = Dictionary::getLanguages(true); - - //load the page accordingly to the link - switch ($this->page) { - case 'messages': - //renders the message edit page - Render::addTemplate('translation/edit', array( - 'path' => 'messages', - 'langs' => $langs, - 'tags' => $this->loadMessageEditArray() - )); - break; - case 'hardcoded': - //renders the hardcoded messages edit page - Render::addTemplate('translation/edit', array( - 'path' => 'messages-hardcoded', - 'langs' => $langs, - 'tags' => $this->loadHardcodedStringEditArray() - )); - break; - case 'settings': - //renders the settings related edit page - Render::addTemplate('translation/edit', array( - 'path' => 'settings/cat_setting', - 'langs' => $langs, - 'tags' => $this->loadCategoriesArray() - )); - Render::addTemplate('translation/edit', array( - 'path' => 'settings/setting', - 'langs' => $langs, - 'tags' => $this->loadSettingsArray() - )); - break; - case 'config-module': - //renders the hardcoded messages edit page - Render::addTemplate('translation/edit', array( - 'path' => 'config-module', - 'langs' => $langs, - 'tags' => $this->buildTranslationTable('config-module') - )); - break; - case 'template': - $this->template = Util::safePath($this->template); - if ($this->template === false) { - Message::addError('invalid-path'); - Util::redirect('?do=Translation'); - } - //renders the tag edition page - Render::addTemplate('translation/edit', array( - 'path' => 'templates/' . $this->template, - 'langs' => $langs, - 'tags' => $this->loadTemplateEditArray($this->template) - )); - break; - case 'templates': - //renders the template selection page - Render::addTemplate('translation/template-list', array( - 'table' => $this->loadTemplatesList(), - )); - break; - default: - //renders main page with selection of what part to edit - Render::addTemplate('translation/_page'); - } - } - - /** - * Load the main table with all the website's templates and it's informations - * @return array with the templates' information - */ - private function loadTemplatesList() - { - $table = array(); - - //loads every template - $files = $this->listTemplates(); - $langs = Dictionary::getLanguages(true); - - //checks the JSON tags from every language - foreach ($files as $file) { - $tags = $this->loadTemplateTags($file['path']); - // Don't list templates without lang tags - if (empty($tags)) - continue; - $msgs = ''; - foreach ($langs as $lang) { - $msg = $this->checkJson($file['path'], $lang['cc'], $tags); - if (!empty($msg)) - $msgs .= "
{$lang['name']}:$msg
"; - } - if (empty($msgs)) - $msgs = 'OK'; - $table[] = array( - 'template' => $file['name'], - 'link' => $file['name'], - 'status' => $msgs - ); - } - sort($table); - return $table; - } - - /** - * Finds and returns all the website's templates - * @return array - */ - private function listTemplates() - { - $files = array(); - $dir = 'templates/'; - $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); - foreach ($objects as $name => $object) { - if (substr($name, -5) === '.html') { - $files[] = array( - 'path' => substr($name, 0, -5), - 'name' => substr($name, strlen($dir), -5) - ); - } - } - return $files; - } - - /** - * Finds and returns all PHP files of slxadmin - * @return array of all php files - */ - private function listPhp() - { - $php = array(); - $dir = '.'; - $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); - foreach ($objects as $name => $object) { - if (substr($name, -4) === '.php') { - $php[] = $name; - } - } - return $php; - } - - /** - * Checks the JSON tags from a template - * @param string the template's path - * @param string the selected language - * @param string tags that should be in the json file - * @return string|boolean the information about the JSON tags, false if template has no lang-tags - */ - private function checkJson($path, $lang, $expectedTags) - { - //if there was not a valid template's path - if (!$path) { - return "Translation missing"; - } - // How many tags do we expect in the translation - $htmlCount = count($expectedTags); - - //initialize the count variables - $matchCount = 0; - $unusedCount = 0; - - //loads the JSON tags and count the matches - $json = Dictionary::getArray($path, $lang); - //return print_r($json) . "\nvs\n" . print_r($expectedTags); - foreach ($json as $key => $value) { - if (!in_array($key, $expectedTags)) { - $unusedCount++; - } else if (!empty($value)) { - $matchCount++; - } - } - $diff = $htmlCount - $matchCount; - - if ($diff == 0 && $unusedCount == 0) - return ''; - //build the return string - $str = ""; - if ($diff > 0) - $str .= $diff . " JSON tag(s) are missing"; - if ($diff > 0 && $unusedCount > 0) - $str .= "
"; - if ($unusedCount > 0) - $str .= $unusedCount . " JSON tag(s) are not being used"; - return $str; - } - - /** - * Get array to pass to edit page with all the tags and translations for the given template - * @param string $path the template's path - * @return array the information about the JSON tags - */ - private function loadTemplateEditArray($path) - { - $path = "templates/$path"; - $tags = $this->loadTemplateTags($path); - if ($tags === false) - return false; - return $this->buildTranslationTable($path, $tags); - } - - /** - * Load array of tags used in given template. - * @param string $path the path of the template, relative to templates/, without .html extension. - * @return array all tags in template - */ - private function loadTemplateTags($path) - { - $templateFile = "$path.html"; - //checks if the template is valid - if (!file_exists($templateFile)) { - Message::addError('invalid-template', $templateFile); - return false; - } - - //finds every mustache tag within the html template - $htmlTemplate = file_get_contents($templateFile); - preg_match_all('/{{(lang_.*?)}}/s', $htmlTemplate, $matches); - if (!isset($matches[1]) || !is_array($matches[1])) - return array(); - return array_unique($matches[1]); - } - - /** - * Load array of tags and translations of all messages - * @return array the information about the JSON tags - */ - private function loadMessageEditArray() - { - $tags = $this->loadTagsFromPhp('/Message\s*::\s*add\w+\s*\(\s*[\'"](.*?)[\'"]\s*[\)\,]/i'); - if ($tags === false) - return false; - return $this->buildTranslationTable('messages', $tags); - } - - /** - * Load array of tags and translations of all strings found in the php files. - * @return array the information about the JSON tags - */ - private function loadHardcodedStringEditArray() - { - $tags = $this->loadTagsFromPhp('/Dictionary\s*::\s*translate\s*\(\s*[\'"]([^\'"]*?)[\'"]\s*\)/i'); - if ($tags === false) - return false; - return $this->buildTranslationTable('messages-hardcoded', $tags); - } - - /** - * Load array of tags used in all the php files, by given regexp. Capture group 1 should return - * the exact tag name. - * @param string $regexp regular expression matching all tags in capture group 1 - * @return array of all tags found - */ - private function loadTagsFromPhp($regexp) - { - // Get all php files, so we can find all strings that need to be translated - $php = $this->listPhp(); - $tags = array(); - // Now find all tags in all php files. Only works for literal usage, not something like $foo = 'bar'; Dictionary::translate($foo); - foreach ($php as $file) { - $content = @file_get_contents($file); - if ($content === false || preg_match_all($regexp, $content, $out) < 1) - continue; - foreach ($out[1] as $id) { - $tags[$id] = true; - } - } - return array_keys($tags); - } - - private function buildTranslationTable($path, $requiredTags = false) - { - // All languages - $langArray = Dictionary::getLanguages(); - - $tags = array(); - if ($requiredTags !== false) { - foreach ($requiredTags as $tagName) { - $tags[$tagName] = array('tag' => $tagName); - foreach ($langArray as $lang) { - $tags[$tagName]['langs'][$lang]['lang'] = $lang; - $tags[$tagName]['missing'] = count($langArray); - } - } - } - // Finds every JSON tag withing the JSON language files - foreach ($langArray as $lang) { - $jsonTags = Dictionary::getArray($path, $lang); - if (!is_array($jsonTags)) - continue; - foreach ($jsonTags as $tag => $translation) { - $tags[$tag]['langs'][$lang]['translation'] = $translation; - $tags[$tag]['langs'][$lang]['lang'] = $lang; - if (strpos($translation, "\n") !== false) - $tags[$tag]['langs'][$lang]['big'] = true; - $tags[$tag]['tag'] = $tag; - if (!isset($tags[$tag]['missing'])) - $tags[$tag]['missing'] = 0; - if (!empty($translation)) - $tags[$tag]['missing'] --; - } - } - // Fill the blanks - foreach ($langArray as $lang) { - foreach (array_keys($tags) as $tagName) { - if (!isset($tags[$tagName]['langs'][$lang])) - $tags[$tagName]['langs'][$lang]['lang'] = $lang; - } - } - // Finally remove $lang from the keys so mustache will iterate over them via {{#..}} - foreach ($tags as &$tag) { - $tag['langs'] = array_values($tag['langs']); - if ($requiredTags !== false) - $tag['class'] = $this->getTagColor($tag['missing']); - } - return array_values($tags); - } - - /** - * Change the color of the table line according to the tag status - * @param string the JSON's path - * @param string the selected tag - * @return string the css class of the line - */ - private function getTagColor($missingCount) - { - //return danger in case the tag is not found in the template - if ($missingCount < 0) - return 'danger'; - - //return warning in case at least one of the tag's values is empty - if ($missingCount > 0) - return 'warning'; - //if it's ok don't change the class - return ''; - } - - /** - * Updates a JSON file with it's new tags or/and tags values - */ - private function updateJson() - { - $langArray = Dictionary::getLanguages(); - foreach ($langArray as $lang) { - $json[$lang] = array(); - } - - //find the tag requests to change the file - foreach ($_POST as $key => $value) { - $str = explode('#', $key, 3); - if (count($str) !== 3 || $str[0] !== 'lang') - continue; - $lang = $str[1]; - $tag = trim($str[2]); - if (!isset($json[$lang])) { - Message::addWarning('i18n-invalid-lang', $lang); - continue; - } - if (empty($tag)) { - Message::addWarning('i18n-empty-tag'); - continue; - } - $value = trim($value); - if ($tag !== 'newtag') { - if (empty($value)) { - unset($json[$lang][$tag]); - } else { - $json[$lang][$tag] = $value; - } - } else { - if (!empty($value)) // TODO: Error message if new tag's name collides with existing - $json[$lang][$_REQUEST['newtag']] = $value; - } - } - - // JSON_PRETTY_PRINT is only available starting with php 5.4.0.... Use upgradephp's json_encode - require_once('inc/up_json_encode.php'); - - //saves the new values on the file - foreach ($json as $key => $array) { - $path = Util::safePath('lang/' . $key . '/' . Request::post('path') . '.json'); - if ($path === false) { - Message::addError('invalid-path'); - Util::redirect('?do=Translation'); - } - @mkdir(dirname($path), 0755, true); - ksort($array); // Sort by key, so the diff on the output is cleaner - $json = up_json_encode($array, JSON_PRETTY_PRINT); // Also for better diffability of the json files, we pretty print - //exits the function in case the action was unsuccessful - if (@file_put_contents($path, $json) === false) { - Message::addError('invalid-template'); - return; - } - } - Message::addSuccess('updated-tags'); - } - - /** - * Delete a specific JSON tag from a JSON files - * @var string the JSON's file path - * @var the JSON tag to be deleted - * @return boolean if the action was not successful - */ - private function deleteTag($path, $tag) - { - // JSON_PRETTY_PRINT is only available starting with php 5.4.0.... Use upgradephp's json_encode - require_once('inc/up_json_encode.php'); - - //delete the tag from every language file - $langArray = Dictionary::getLanguages(); - foreach ($langArray as $lang) { - $json = Dictionary::getArray($path, $lang); - unset($json[$tag]); - $result = file_put_contents('lang/' . $lang . '/' . $path . '.json', up_json_encode($json, JSON_PRETTY_PRINT)); - //add warning and exit in case the action was unsuccessful - if ($result === false) { - Message::addWarning('unsuccessful-action'); - return false; - } - } - Message::addSuccess('deleted-tag'); - } - - /** - * Load all settings categories for editing. - * - * @return array - */ - private function loadCategoriesArray() - { - $want = array(); - $res = Database::simpleQuery("SELECT catid FROM cat_setting ORDER BY catid ASC"); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $want[] = 'cat_' . $row['catid']; - } - return $this->buildTranslationTable('settings/cat_setting', $want); - } - - /** - * Load all settings categories for editing. - * - * @return array - */ - private function loadSettingsArray() - { - $want = array(); - $res = Database::simpleQuery("SELECT setting FROM setting ORDER BY setting ASC"); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $want[] = $row['setting']; - } - return $this->buildTranslationTable('settings/setting', $want); - } - -} diff --git a/modules/translation/config.json b/modules/translation/config.json new file mode 100644 index 00000000..4e7fa5fb --- /dev/null +++ b/modules/translation/config.json @@ -0,0 +1,4 @@ +{ + "category":"content", + "enabled":"true" +} diff --git a/modules/translation/module.inc.php b/modules/translation/module.inc.php new file mode 100644 index 00000000..3548f727 --- /dev/null +++ b/modules/translation/module.inc.php @@ -0,0 +1,597 @@ +updateJson(); + Util::redirect('?do=Translation'); + } + if (Request::post('delete')) { + $this->deleteTag(Request::post('path'), Request::post('delete')); + Util::redirect('?do=Translation'); // TODO: Ajax post for delete so we stay on the page + } + + $this->template = Request::get('template'); + $this->page = Request::get('page'); + } + + protected function doRender() + { + $langs = Dictionary::getLanguages(true); + + //load the page accordingly to the link + switch ($this->page) { + case 'messages': + //renders the message edit page + Render::addTemplate('edit', array( + 'path' => 'messages', + 'langs' => $langs, + 'tags' => $this->loadMessageEditArray() + )); + break; + case 'hardcoded': + //renders the hardcoded messages edit page + Render::addTemplate('edit', array( + 'path' => 'messages-hardcoded', + 'langs' => $langs, + 'tags' => $this->loadHardcodedStringEditArray() + )); + break; + case 'settings': + //renders the settings related edit page + Render::addTemplate('edit', array( + 'path' => 'cat_setting', + 'langs' => $langs, + 'tags' => $this->loadCategoriesArray() + )); + Render::addTemplate('edit', array( + 'path' => 'setting', + 'langs' => $langs, + 'tags' => $this->loadSettingsArray() + )); + break; + case 'config-module': + //renders the hardcoded messages edit page + Render::addTemplate('edit', array( + 'path' => 'config-module', + 'langs' => $langs, + 'tags' => $this->buildTranslationTable('config-module') + )); + break; + case 'template': + $this->template = Util::safePath($this->template); + if ($this->template === false) { + Message::addError('invalid-path'); + Util::redirect('?do=Translation'); + } + //renders the tag edition page + Render::addTemplate('edit', array( + 'path' => 'modules/' . $this->template, + 'langs' => $langs, + 'tags' => $this->loadTemplateEditArray($this->template) + )); + break; + case 'templates': + //renders the template selection page + Render::addTemplate('template-list', array( + 'table' => $this->loadTemplatesList(), + )); + break; + case 'modules': + Render::addTemplate('module-list', array( + 'table' => $this->loadModuleTable() + )); + break; + default: + //renders main page with selection of what part to edit + Render::addTemplate('_page'); + } + } + + private function loadModuleTable(){ + $table = array(); + + $modules = $this->loadModuleList(); + + foreach ($modules as $module) { + $msgs = $this->checkModuleTranslation($module); + $table[] = array( + 'module' => $module, + 'status' => $msgs + ); + } + + sort($table); + return $table; + } + + private function loadModuleEdit(){ + $table = array(); + $tags = array_flip($this->loadModuleTags($this->module)); + foreach ($this->langs as $lang) { + $tags = array_merge($tags, Dictionary::getArray($this->module,$lang['cc'])); + } + foreach ($tags as $tag => $value) { + $langArray = array(); + $class = ''; + foreach ($this->langs as $lang) { + $translations = Dictionary::getArray($this->module,$lang['cc']); + $langArray[] = array( + 'lang' => $lang['cc'], + 'placeholder' => 'TAG - ' . $lang['name'], + 'translation' => $translations[$tag] + ); + if(!in_array($tag, $this->loadModuleTags($this->module))) + $class = 'danger'; + else if(!$translations[$tag]) + $class = 'warning'; + } + $table[] = array( + 'tag' => $tag, + 'class' => $class, + 'langs' => $langArray + ); + } + + return $table; + } + + private function loadModuleList(){ + // Return an array with the modules and the tags data + $list = array(); + $list = array_diff(scandir('modules/'), array('..', '.')); + return $list; + } + + private function loadModuleTags($module){ + // Return an array with the module language tags + $path = "modules/" . $module . "templates/"; + $files = array_diff(scandir($path), array('..', '.')); + $tags = array(); + foreach ($files as $file) { + $content = file_get_contents($path . $file); + preg_match_all('/{{(lang_.*?)}}/s', $content, $matches); + if (isset($matches[1]) && is_array($matches[1])){ + $tags = array_merge($tags,array_unique($matches[1])); + } + } + return array_unique($tags); + } + + private function checkModuleTranslation($module){ + $tags = $this->loadModuleTags($module); + $translation = array(); + $msgs = ''; + foreach ($this->langs as $key => $lang) { + $translation = Dictionary::getArray($module,$lang['cc']); + $matches = 0; + $unused = 0; + $expected = count($tags); + foreach ($translation as $key => $value) { + if(!in_array($key, $tags)) + $unused ++; + else if(!empty($value)) + $matches ++; + + } + + $diff = $expected - $matches; + $msg = ""; + if ($diff > 0) + $msg .= $diff . " JSON tag(s) are missing"; + if ($diff > 0 && $unused > 0) + $msg .= "
"; + if ($unused > 0) + $msg .= $unused . " JSON tag(s) are not being used"; + if(!empty($msg)) + $msgs .= "
{$lang['name']}: $msg
"; + } + if(empty($msgs)) + $msgs = 'OK'; + return $msgs; + } + /** + * Load the main table with all the website's templates and it's informations + * @return array with the templates' information + */ + private function loadTemplatesList() + { + $table = array(); + + //loads every template + $files = $this->listTemplates(); + $langs = Dictionary::getLanguages(true); + + //checks the JSON tags from every language + foreach ($files as $file) { + $tags = $this->loadTemplateTags($file['path']); + // Don't list templates without lang tags + if (empty($tags)) + continue; + $msgs = ''; + foreach ($langs as $lang) { + $msg = $this->checkJson($file['path'], $lang['cc'], $tags); + if (!empty($msg)) + $msgs .= "
{$lang['name']}:$msg
"; + } + if (empty($msgs)) + $msgs = 'OK'; + $table[] = array( + 'template' => $file['name'], + 'link' => $file['name'], + 'status' => $msgs + ); + } + sort($table); + return $table; + } + + /** + * Finds and returns all the website's templates + * @return array + */ + private function listTemplates() + { + $files = array(); + $dir = 'modules/'; + $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); + foreach ($objects as $name => $object) { + if (substr($name, -5) === '.html') { + $files[] = array( + 'path' => substr($name, 0, -5), + 'name' => substr($name, strlen($dir), -5) + ); + } + } + return $files; + } + + /** + * Finds and returns all PHP files of slxadmin + * @return array of all php files + */ + private function listPhp() + { + $php = array(); + $dir = '.'; + $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); + foreach ($objects as $name => $object) { + if (substr($name, -4) === '.php') { + $php[] = $name; + } + } + return $php; + } + + /** + * Checks the JSON tags from a template + * @param string the template's path + * @param string the selected language + * @param string tags that should be in the json file + * @return string|boolean the information about the JSON tags, false if template has no lang-tags + */ + private function checkJson($path, $lang, $expectedTags) + { + //if there was not a valid template's path + if (!$path) { + return "Translation missing"; + } + // How many tags do we expect in the translation + $htmlCount = count($expectedTags); + + //initialize the count variables + $matchCount = 0; + $unusedCount = 0; + + //loads the JSON tags and count the matches + $json = Dictionary::getArray(substr($path, strlen("modules/")), $lang); + //return print_r($json) . "\nvs\n" . print_r($expectedTags); + foreach ($json as $key => $value) { + if (!in_array($key, $expectedTags)) { + $unusedCount++; + } else if (!empty($value)) { + $matchCount++; + } + } + $diff = $htmlCount - $matchCount; + + if ($diff == 0 && $unusedCount == 0) + return ''; + //build the return string + $str = ""; + if ($diff > 0) + $str .= $diff . " JSON tag(s) are missing"; + if ($diff > 0 && $unusedCount > 0) + $str .= "
"; + if ($unusedCount > 0) + $str .= $unusedCount . " JSON tag(s) are not being used"; + return $str; + } + + /** + * Get array to pass to edit page with all the tags and translations for the given template + * @param string $path the template's path + * @return array the information about the JSON tags + */ + private function loadTemplateEditArray($path) + { + $tags = $this->loadTemplateTags($path); + if ($tags === false) + return false; + return $this->buildTranslationTable("modules/" . $path, $tags); + } + + /** + * Load array of tags used in given template. + * @param string $path the path of the template, relative to templates/, without .html extension. + * @return array all tags in template + */ + private function loadTemplateTags($path) + { + $templateFile = "$path.html"; + //checks if the template is valid + if (!file_exists($templateFile)) { + Message::addError('invalid-template', $templateFile); + return false; + } + + //finds every mustache tag within the html template + $htmlTemplate = file_get_contents($templateFile); + preg_match_all('/{{(lang_.*?)}}/s', $htmlTemplate, $matches); + if (!isset($matches[1]) || !is_array($matches[1])) + return array(); + return array_unique($matches[1]); + } + + /** + * Load array of tags and translations of all messages + * @return array the information about the JSON tags + */ + private function loadMessageEditArray() + { + $tags = $this->loadTagsFromPhp('/Message\s*::\s*add\w+\s*\(\s*[\'"](.*?)[\'"]\s*[\)\,]/i'); + if ($tags === false) + return false; + return $this->buildTranslationTable('messages', $tags); + } + + /** + * Load array of tags and translations of all strings found in the php files. + * @return array the information about the JSON tags + */ + private function loadHardcodedStringEditArray() + { + $tags = $this->loadTagsFromPhp('/Dictionary\s*::\s*translate\s*\(\s*[\'"]([^\'"]*?)[\'"]\s*\)/i'); + if ($tags === false) + return false; + return $this->buildTranslationTable('messages-hardcoded', $tags); + } + + /** + * Load array of tags used in all the php files, by given regexp. Capture group 1 should return + * the exact tag name. + * @param string $regexp regular expression matching all tags in capture group 1 + * @return array of all tags found + */ + private function loadTagsFromPhp($regexp) + { + // Get all php files, so we can find all strings that need to be translated + $php = $this->listPhp(); + $tags = array(); + // Now find all tags in all php files. Only works for literal usage, not something like $foo = 'bar'; Dictionary::translate($foo); + foreach ($php as $file) { + $content = @file_get_contents($file); + if ($content === false || preg_match_all($regexp, $content, $out) < 1) + continue; + foreach ($out[1] as $id) { + $tags[$id] = true; + } + } + return array_keys($tags); + } + + private function buildTranslationTable($path, $requiredTags = false) + { + // All languages + $langArray = Dictionary::getLanguages(); + + $tags = array(); + if ($requiredTags !== false) { + foreach ($requiredTags as $tagName) { + $tags[$tagName] = array('tag' => $tagName); + foreach ($langArray as $lang) { + $tags[$tagName]['langs'][$lang]['lang'] = $lang; + $tags[$tagName]['missing'] = count($langArray); + } + } + } + // Finds every JSON tag within the JSON language files + foreach ($langArray as $lang) { + $jsonTags = Dictionary::getArray($path, $lang, true); + if (!is_array($jsonTags)) + continue; + foreach ($jsonTags as $tag => $translation) { + $tags[$tag]['langs'][$lang]['translation'] = $translation; + $tags[$tag]['langs'][$lang]['lang'] = $lang; + if (strpos($translation, "\n") !== false) + $tags[$tag]['langs'][$lang]['big'] = true; + $tags[$tag]['tag'] = $tag; + if (!isset($tags[$tag]['missing'])) + $tags[$tag]['missing'] = 0; + if (!empty($translation)) + $tags[$tag]['missing'] --; + } + } + // Fill the blanks + foreach ($langArray as $lang) { + foreach (array_keys($tags) as $tagName) { + if (!isset($tags[$tagName]['langs'][$lang])) + $tags[$tagName]['langs'][$lang]['lang'] = $lang; + } + } + // Finally remove $lang from the keys so mustache will iterate over them via {{#..}} + foreach ($tags as &$tag) { + $tag['langs'] = array_values($tag['langs']); + if ($requiredTags !== false) + $tag['class'] = $this->getTagColor($tag['missing']); + } + return array_values($tags); + } + + /** + * Change the color of the table line according to the tag status + * @param string the JSON's path + * @param string the selected tag + * @return string the css class of the line + */ + private function getTagColor($missingCount) + { + //return danger in case the tag is not found in the template + if ($missingCount < 0) + return 'danger'; + + //return warning in case at least one of the tag's values is empty + if ($missingCount > 0) + return 'warning'; + //if it's ok don't change the class + return ''; + } + + /** + * Updates a JSON file with it's new tags or/and tags values + */ + private function updateJson() + { + $langArray = Dictionary::getLanguages(); + foreach ($langArray as $lang) { + $json[$lang] = array(); + } + + //find the tag requests to change the file + foreach ($_POST as $key => $value) { + $str = explode('#', $key, 3); + if (count($str) !== 3 || $str[0] !== 'lang') + continue; + $lang = $str[1]; + $tag = trim($str[2]); + if (!isset($json[$lang])) { + Message::addWarning('i18n-invalid-lang', $lang); + continue; + } + if (empty($tag)) { + Message::addWarning('i18n-empty-tag'); + continue; + } + $value = trim($value); + if ($tag !== 'newtag') { + if (empty($value)) { + unset($json[$lang][$tag]); + } else { + $json[$lang][$tag] = $value; + } + } else { + if (!empty($value)) // TODO: Error message if new tag's name collides with existing + $json[$lang][$_REQUEST['newtag']] = $value; + } + } + + // JSON_PRETTY_PRINT is only available starting with php 5.4.0.... Use upgradephp's json_encode + require_once('inc/up_json_encode.php'); + + //saves the new values on the file + foreach ($json as $key => $array) { + $path = Util::safePath('lang/' . $key . '/' . Request::post('path') . '.json'); + if ($path === false) { + Message::addError('invalid-path'); + Util::redirect('?do=Translation'); + } + @mkdir(dirname($path), 0755, true); + ksort($array); // Sort by key, so the diff on the output is cleaner + $json = up_json_encode($array, JSON_PRETTY_PRINT); // Also for better diffability of the json files, we pretty print + //exits the function in case the action was unsuccessful + if (@file_put_contents($path, $json) === false) { + Message::addError('invalid-template'); + return; + } + } + Message::addSuccess('updated-tags'); + } + + /** + * Delete a specific JSON tag from a JSON files + * @var string the JSON's file path + * @var the JSON tag to be deleted + * @return boolean if the action was not successful + */ + private function deleteTag($path, $tag) + { + // JSON_PRETTY_PRINT is only available starting with php 5.4.0.... Use upgradephp's json_encode + require_once('inc/up_json_encode.php'); + + //delete the tag from every language file + $langArray = Dictionary::getLanguages(); + foreach ($langArray as $lang) { + $json = Dictionary::getArray($path, $lang); + unset($json[$tag]); + $result = file_put_contents('lang/' . $lang . '/' . $path . '.json', up_json_encode($json, JSON_PRETTY_PRINT)); + //add warning and exit in case the action was unsuccessful + if ($result === false) { + Message::addWarning('unsuccessful-action'); + return false; + } + } + Message::addSuccess('deleted-tag'); + } + + /** + * Load all settings categories for editing. + * + * @return array + */ + private function loadCategoriesArray() + { + $want = array(); + $res = Database::simpleQuery("SELECT catid FROM cat_setting ORDER BY catid ASC"); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $want[] = 'cat_' . $row['catid']; + } + return $this->buildTranslationTable('settings/cat_setting', $want); + } + + /** + * Load all settings categories for editing. + * + * @return array + */ + private function loadSettingsArray() + { + $want = array(); + $res = Database::simpleQuery("SELECT setting FROM setting ORDER BY setting ASC"); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $want[] = $row['setting']; + } + return $this->buildTranslationTable('settings/setting', $want); + } + +} diff --git a/modules/translation/templates/_page.html b/modules/translation/templates/_page.html new file mode 100644 index 00000000..52a4c94b --- /dev/null +++ b/modules/translation/templates/_page.html @@ -0,0 +1,17 @@ + diff --git a/modules/translation/templates/edit.html b/modules/translation/templates/edit.html new file mode 100644 index 00000000..dc01deb6 --- /dev/null +++ b/modules/translation/templates/edit.html @@ -0,0 +1,71 @@ +
+
+
+ {{path}} +
+
+

{{lang_templateAdminHelp}}

+
+ {{lang_templateHint}} +
+
+ + + {{lang_back}} + + + + + + + {{#langs}} + + {{/langs}} + + + + + {{#tags}} + + + {{#langs}} + + {{/langs}} + + + {{/tags}} + + + +
Mustache Tag{{name}}
{{tag}} + {{^big}} + + {{/big}} + {{#big}} + + {{/big}} + + +
+ {{lang_back}} + + +
+
+
+
+ diff --git a/modules/translation/templates/module-list.html b/modules/translation/templates/module-list.html new file mode 100644 index 00000000..037a21bc --- /dev/null +++ b/modules/translation/templates/module-list.html @@ -0,0 +1,32 @@ +
+
+ {{lang_langAdministration}} +
+
+

{{lang_adminInfo}}

+
+
+
+ + + + + + + + + {{#table}} + + + + + {{/table}} + +
{{lang_module}}{{lang_status}}
{{module}}{{{status}}}
+
+ + diff --git a/modules/translation/templates/template-list.html b/modules/translation/templates/template-list.html new file mode 100644 index 00000000..881fc5af --- /dev/null +++ b/modules/translation/templates/template-list.html @@ -0,0 +1,32 @@ +
+
+ {{lang_langAdministration}} +
+
+

{{lang_adminInfo}}

+
+
+
+ + + + + + + + + {{#table}} + + + + + {{/table}} + +
Template{{lang_status}}
{{template}}{{{status}}}
+
+ + diff --git a/modules/usermanagement/config.json b/modules/usermanagement/config.json new file mode 100644 index 00000000..90787d94 --- /dev/null +++ b/modules/usermanagement/config.json @@ -0,0 +1,5 @@ +{ + "category":"users", + "enabled":"true", + "permission":"0" +} diff --git a/modules/usermanagement/module.inc.php b/modules/usermanagement/module.inc.php new file mode 100644 index 00000000..01b5f755 --- /dev/null +++ b/modules/usermanagement/module.inc.php @@ -0,0 +1,109 @@ +page = $p; + else + $this->page = 1; + + switch(Request::post('action')){ + case "editAdmin": + $this->edit(Request::post('userid'),Request::post('username'),Request::post('phone'),Request::post('email'), 1); + break; + case "edit": + $this->edit(Request::post('userid'),Request::post('username'),Request::post('phone'),Request::post('email'), 4); + break; + case "create": + $this->create(Request::post('login'),Request::post('username'),Request::post('pass'),Request::post('phone'),Request::post('email'), 4); + break; + case "delete": + $this->delete(Request::post('userid')); + break; + } + + if(isset($_POST['userid'])) + $this->deb = $_POST['userid']; + + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=Main'); + } + + } + + protected function doRender() + { + // load every user + $admin = array(); + $users = array(); + $res = Database::simpleQuery("SELECT userid, login, fullname, phone, email, permissions FROM user ORDER BY userid DESC"); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['permissions'] == 1 ) + $admin = array($row['userid'],$row['login'],$row['fullname'],$row['phone'],$row['email']); + else + $users[] = array( + 'id' => $row['userid'], + 'username' => $row['login'], + 'name' => $row['fullname'], + 'telephone' => $row['phone'], + 'email' => $row['email'] + ); + } + + //$pag = new Paginate($users,$this->page); + + Render::addTemplate('user-management', array( + 'admin_id' => $admin[0], + 'admin_username' => $admin[1], + 'admin_name' => $admin[2], + 'admin_telephone' => $admin[3], + 'admin_email' => $admin[4] + //'users' => $pag->getItems(), + //'pages' => $pag->getPagination() + )); + } + + private function edit($userid, $newname, $newphone, $newemail, $newpermissions){ + $data = array ( + 'user' => $userid, + 'name' => $newname, + 'phone' => $newphone, + 'email' => $newemail, + 'permissions' => $newpermissions + ); + Database::exec ( 'UPDATE user SET fullname = :name, phone = :phone, email = :email, permissions = :permissions WHERE userid = :user', $data ); + Message::addSuccess('update-user'); + } + + private function create($login, $username, $password, $phone, $email){ + $data = array ( + 'login' => $login, + 'pass' => Crypto::hash6 ( $password ), + 'name' => $username, + 'phone' => $phone, + 'email' => $email + ); + User::addUser($data); + } + + private function delete($userid){ + $data = array ( + 'userid' => $userid + ); + Database::exec ( 'DELETE FROM setting_partition WHERE user = :userid', $data ); + Database::exec ( 'DELETE FROM setting_user WHERE user = :userid', $data ); + Database::exec ( 'DELETE FROM setting_values WHERE user = :userid', $data ); + Database::exec ( 'DELETE FROM user WHERE userid = :userid', $data ); + Message::addSuccess('delete-user'); + } + +} diff --git a/modules/usermanagement/templates/user-management.html b/modules/usermanagement/templates/user-management.html new file mode 100644 index 00000000..fc14355f --- /dev/null +++ b/modules/usermanagement/templates/user-management.html @@ -0,0 +1,127 @@ +
+
+
{{lang_userAdmin}}
+
+ + + + + + + + + + + + + + + + + + + + + +
ID{{lang_login}}{{lang_username}}{{lang_telephone}}{{lang_email}}
+
+ +
+
+
{{lang_userPage}}
+
+
+

+ {{lang_userInfo}} +

+ +
+ + + + + + + + + + + + + + + + + + + {{#users}} + + + + + + {{/users}} + + + +
ID{{lang_login}}{{lang_operations}}
+ +
+ + + +
+
    + {{#pages}} +
  • {{page}}
  • + {{/pages}} +
+
+
+{{#users}} + +{{/users}} \ No newline at end of file diff --git a/modules/vmstore.inc.php b/modules/vmstore.inc.php deleted file mode 100644 index afc5809d..00000000 --- a/modules/vmstore.inc.php +++ /dev/null @@ -1,63 +0,0 @@ -setStore(); - } - } - - protected function doRender() - { - $action = Request::post('action'); - if ($action === 'setstore' && !Taskmanager::isFailed($this->mountTask)) { - Render::addTemplate('vmstore/mount', array( - 'task' => $this->mountTask['id'] - )); - return; - } - $vmstore = Property::getVmStoreConfig(); - if (isset($vmstore['storetype'])) { - $vmstore['pre-' . $vmstore['storetype']] = 'checked'; - } - Render::addTemplate('page-vmstore', $vmstore); - } - - private function setStore() - { - foreach (array('storetype', 'nfsaddr', 'cifsaddr', 'cifsuser', 'cifspasswd', 'cifsuserro', 'cifspasswdro') as $key) { - $vmstore[$key] = trim(Request::post($key, '')); - } - $storetype = $vmstore['storetype']; - if (!in_array($storetype, array('internal', 'nfs', 'cifs'))) { - Message::addError('value-invalid', 'type', $storetype); - Util::redirect('?do=VmStore'); - } - // Validate syntax of nfs/cifs - if ($storetype === 'nfs' && !preg_match('#^\S+:\S+$#is', $vmstore['nfsaddr'])) { - Message::addError('value-invalid', 'nfsaddr', $vmstore['nfsaddr']); - Util::redirect('?do=VmStore'); - } - $vmstore['cifsaddr'] = str_replace('\\', '/', $vmstore['cifsaddr']); - if ($storetype === 'cifs' && !preg_match('#^//\S+/.+$#is', $vmstore['cifsaddr'])) { - Message::addError('value-invalid', 'nfsaddr', $vmstore['nfsaddr']); - Util::redirect('?do=VmStore'); - } - $this->mountTask = Trigger::mount($vmstore); - TaskmanagerCallback::addCallback($this->mountTask, 'manualMount', $vmstore); - } - -} \ No newline at end of file diff --git a/modules/vmstore/config.json b/modules/vmstore/config.json new file mode 100644 index 00000000..93209f62 --- /dev/null +++ b/modules/vmstore/config.json @@ -0,0 +1,4 @@ +{ + "category":"settings", + "enabled":"true" +} diff --git a/modules/vmstore/module.inc.php b/modules/vmstore/module.inc.php new file mode 100644 index 00000000..81f92ee3 --- /dev/null +++ b/modules/vmstore/module.inc.php @@ -0,0 +1,63 @@ +setStore(); + } + } + + protected function doRender() + { + $action = Request::post('action'); + if ($action === 'setstore' && !Taskmanager::isFailed($this->mountTask)) { + Render::addTemplate('mount', array( + 'task' => $this->mountTask['id'] + )); + return; + } + $vmstore = Property::getVmStoreConfig(); + if (isset($vmstore['storetype'])) { + $vmstore['pre-' . $vmstore['storetype']] = 'checked'; + } + Render::addTemplate('page-vmstore', $vmstore); + } + + private function setStore() + { + foreach (array('storetype', 'nfsaddr', 'cifsaddr', 'cifsuser', 'cifspasswd', 'cifsuserro', 'cifspasswdro') as $key) { + $vmstore[$key] = trim(Request::post($key, '')); + } + $storetype = $vmstore['storetype']; + if (!in_array($storetype, array('internal', 'nfs', 'cifs'))) { + Message::addError('value-invalid', 'type', $storetype); + Util::redirect('?do=VmStore'); + } + // Validate syntax of nfs/cifs + if ($storetype === 'nfs' && !preg_match('#^\S+:\S+$#is', $vmstore['nfsaddr'])) { + Message::addError('value-invalid', 'nfsaddr', $vmstore['nfsaddr']); + Util::redirect('?do=VmStore'); + } + $vmstore['cifsaddr'] = str_replace('\\', '/', $vmstore['cifsaddr']); + if ($storetype === 'cifs' && !preg_match('#^//\S+/.+$#is', $vmstore['cifsaddr'])) { + Message::addError('value-invalid', 'nfsaddr', $vmstore['nfsaddr']); + Util::redirect('?do=VmStore'); + } + $this->mountTask = Trigger::mount($vmstore); + TaskmanagerCallback::addCallback($this->mountTask, 'manualMount', $vmstore); + } + +} \ No newline at end of file diff --git a/modules/vmstore/templates/mount.html b/modules/vmstore/templates/mount.html new file mode 100644 index 00000000..eabee81a --- /dev/null +++ b/modules/vmstore/templates/mount.html @@ -0,0 +1,25 @@ +
+
+ {{lang_vmLocationConfiguration}} +
+ +
+
{{lang_configure}}
+ +
+ + + +
+
\ No newline at end of file diff --git a/modules/vmstore/templates/page-vmstore.html b/modules/vmstore/templates/page-vmstore.html new file mode 100644 index 00000000..fe2c5225 --- /dev/null +++ b/modules/vmstore/templates/page-vmstore.html @@ -0,0 +1,111 @@ +
+ + + + +
+
+ {{lang_vmLocation}} +
+
+

{{lang_vmLocationChoose}}

+
+
+ {{lang_intern}} +
+
+ {{lang_noAdditionalInformation}} +
+
+
+
+ NFS + +
+
+ + +
+
+
+
+ CIFS +
+
+ + +
+ +
+ + {{lang_username}} + + + + {{lang_password}} + + +
+
+ +
+ + {{lang_username}} + + + + {{lang_password}} + + +
+
+
+ +
+
+
+ + + + diff --git a/modules/webinterface.inc.php b/modules/webinterface.inc.php deleted file mode 100644 index cecccacd..00000000 --- a/modules/webinterface.inc.php +++ /dev/null @@ -1,85 +0,0 @@ -actionConfigureHttps(); - break; - case 'password': - $this->actionShowHidePassword(); - break; - } - } - - private function actionConfigureHttps() - { - $task = false; - switch (Request::post('mode')) { - case 'off': - $task = $this->setHttpsOff(); - break; - case 'random': - $task = $this->setHttpsRandomCert(); - break; - case 'custom': - $task = $this->setHttpsCustomCert(); - break; - } - if (isset($task['id'])) { - Session::set('https-id', $task['id']); - Util::redirect('?do=WebInterface&show=httpsupdate'); - } - } - - private function actionShowHidePassword() - { - Property::setPasswordFieldType(Request::post('mode') === 'show' ? 'text' : 'password'); - Util::redirect('?do=WebInterface'); - } - - protected function doRender() - { - Render::setTitle(Dictionary::translate('lang_titleWebinterface')); - if (Request::get('show') === 'httpsupdate') { - Render::addTemplate('webinterface/httpd-restart', array('taskid' => Session::get('https-id'))); - } - Render::addTemplate('webinterface/https', array('httpsEnabled' => file_exists('/etc/lighttpd/server.pem'))); - $data = array(); - if (Property::getPasswordFieldType() === 'text') - $data['selected_show'] = 'checked'; - else - $data['selected_hide'] = 'checked'; - Render::addTemplate('webinterface/passwords', $data); - } - - private function setHttpsOff() - { - return Taskmanager::submit('LighttpdHttps', array()); - } - - private function setHttpsRandomCert() - { - return Taskmanager::submit('LighttpdHttps', array( - 'proxyip' => Property::getServerIp() - )); - } - - private function setHttpsCustomCert() - { - return Taskmanager::submit('LighttpdHttps', array( - 'importcert' => Request::post('certificate', 'bla'), - 'importkey' => Request::post('privatekey', 'bla'), - 'importchain' => Request::post('cachain', '') - )); - } - -} diff --git a/modules/webinterface/config.json b/modules/webinterface/config.json new file mode 100644 index 00000000..4e7fa5fb --- /dev/null +++ b/modules/webinterface/config.json @@ -0,0 +1,4 @@ +{ + "category":"content", + "enabled":"true" +} diff --git a/modules/webinterface/module.inc.php b/modules/webinterface/module.inc.php new file mode 100644 index 00000000..c301dec9 --- /dev/null +++ b/modules/webinterface/module.inc.php @@ -0,0 +1,85 @@ +actionConfigureHttps(); + break; + case 'password': + $this->actionShowHidePassword(); + break; + } + } + + private function actionConfigureHttps() + { + $task = false; + switch (Request::post('mode')) { + case 'off': + $task = $this->setHttpsOff(); + break; + case 'random': + $task = $this->setHttpsRandomCert(); + break; + case 'custom': + $task = $this->setHttpsCustomCert(); + break; + } + if (isset($task['id'])) { + Session::set('https-id', $task['id']); + Util::redirect('?do=WebInterface&show=httpsupdate'); + } + } + + private function actionShowHidePassword() + { + Property::setPasswordFieldType(Request::post('mode') === 'show' ? 'text' : 'password'); + Util::redirect('?do=WebInterface'); + } + + protected function doRender() + { + Render::setTitle(Dictionary::translate('lang_titleWebinterface')); + if (Request::get('show') === 'httpsupdate') { + Render::addTemplate('httpd-restart', array('taskid' => Session::get('https-id'))); + } + Render::addTemplate('https', array('httpsEnabled' => file_exists('/etc/lighttpd/server.pem'))); + $data = array(); + if (Property::getPasswordFieldType() === 'text') + $data['selected_show'] = 'checked'; + else + $data['selected_hide'] = 'checked'; + Render::addTemplate('passwords', $data); + } + + private function setHttpsOff() + { + return Taskmanager::submit('LighttpdHttps', array()); + } + + private function setHttpsRandomCert() + { + return Taskmanager::submit('LighttpdHttps', array( + 'proxyip' => Property::getServerIp() + )); + } + + private function setHttpsCustomCert() + { + return Taskmanager::submit('LighttpdHttps', array( + 'importcert' => Request::post('certificate', 'bla'), + 'importkey' => Request::post('privatekey', 'bla'), + 'importchain' => Request::post('cachain', '') + )); + } + +} diff --git a/modules/webinterface/templates/httpd-restart.html b/modules/webinterface/templates/httpd-restart.html new file mode 100644 index 00000000..cc84aafb --- /dev/null +++ b/modules/webinterface/templates/httpd-restart.html @@ -0,0 +1,6 @@ +
+
{{lang_applyingSettings}}
+
+
{{lang_installAndRestart}}
+
+
diff --git a/modules/webinterface/templates/https.html b/modules/webinterface/templates/https.html new file mode 100644 index 00000000..c6161cd6 --- /dev/null +++ b/modules/webinterface/templates/https.html @@ -0,0 +1,60 @@ +
+ + +
+
{{lang_httpsSettings}}
+
+

{{lang_description}}

+ {{^httpsEnabled}} +

{{lang_HttpsIsDisabled}}

+ {{/httpsEnabled}} + {{#httpsEnabled}} +
+ + + {{lang_noHttps}} + +
+ {{/httpsEnabled}} +
+ + + {{lang_randomCert}} + +
+
+ + + {{lang_customCert}} + +
+ +
+ +
+
+
+
diff --git a/modules/webinterface/templates/passwords.html b/modules/webinterface/templates/passwords.html new file mode 100644 index 00000000..f9fda016 --- /dev/null +++ b/modules/webinterface/templates/passwords.html @@ -0,0 +1,25 @@ +
+ + +
+
{{lang_passwordFields}}
+
+

{{lang_description}}

+
+ + + {{lang_showPasswords}} + +
+
+ + + {{lang_hidePasswords}} + +
+
+ +
+
+
+
diff --git a/script/bootstrap-switch.js b/script/bootstrap-switch.js new file mode 100644 index 00000000..49670481 --- /dev/null +++ b/script/bootstrap-switch.js @@ -0,0 +1,710 @@ +/* ======================================================================== + * bootstrap-switch - v3.3.2 + * http://www.bootstrap-switch.org + * ======================================================================== + * Copyright 2012-2013 Mattia Larentis + * + * ======================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== + */ + +(function() { + var __slice = [].slice; + + (function($, window) { + "use strict"; + var BootstrapSwitch; + BootstrapSwitch = (function() { + function BootstrapSwitch(element, options) { + if (options == null) { + options = {}; + } + this.$element = $(element); + this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, { + state: this.$element.is(":checked"), + size: this.$element.data("size"), + animate: this.$element.data("animate"), + disabled: this.$element.is(":disabled"), + readonly: this.$element.is("[readonly]"), + indeterminate: this.$element.data("indeterminate"), + inverse: this.$element.data("inverse"), + radioAllOff: this.$element.data("radio-all-off"), + onColor: this.$element.data("on-color"), + offColor: this.$element.data("off-color"), + onText: this.$element.data("on-text"), + offText: this.$element.data("off-text"), + labelText: this.$element.data("label-text"), + handleWidth: this.$element.data("handle-width"), + labelWidth: this.$element.data("label-width"), + baseClass: this.$element.data("base-class"), + wrapperClass: this.$element.data("wrapper-class") + }, options); + this.$wrapper = $("
", { + "class": (function(_this) { + return function() { + var classes; + classes = ["" + _this.options.baseClass].concat(_this._getClasses(_this.options.wrapperClass)); + classes.push(_this.options.state ? "" + _this.options.baseClass + "-on" : "" + _this.options.baseClass + "-off"); + if (_this.options.size != null) { + classes.push("" + _this.options.baseClass + "-" + _this.options.size); + } + if (_this.options.disabled) { + classes.push("" + _this.options.baseClass + "-disabled"); + } + if (_this.options.readonly) { + classes.push("" + _this.options.baseClass + "-readonly"); + } + if (_this.options.indeterminate) { + classes.push("" + _this.options.baseClass + "-indeterminate"); + } + if (_this.options.inverse) { + classes.push("" + _this.options.baseClass + "-inverse"); + } + if (_this.$element.attr("id")) { + classes.push("" + _this.options.baseClass + "-id-" + (_this.$element.attr("id"))); + } + return classes.join(" "); + }; + })(this)() + }); + this.$container = $("
", { + "class": "" + this.options.baseClass + "-container" + }); + this.$on = $("", { + html: this.options.onText, + "class": "" + this.options.baseClass + "-handle-on " + this.options.baseClass + "-" + this.options.onColor + }); + this.$off = $("", { + html: this.options.offText, + "class": "" + this.options.baseClass + "-handle-off " + this.options.baseClass + "-" + this.options.offColor + }); + this.$label = $("", { + html: this.options.labelText, + "class": "" + this.options.baseClass + "-label" + }); + this.$element.on("init.bootstrapSwitch", (function(_this) { + return function() { + return _this.options.onInit.apply(element, arguments); + }; + })(this)); + this.$element.on("switchChange.bootstrapSwitch", (function(_this) { + return function() { + return _this.options.onSwitchChange.apply(element, arguments); + }; + })(this)); + this.$container = this.$element.wrap(this.$container).parent(); + this.$wrapper = this.$container.wrap(this.$wrapper).parent(); + this.$element.before(this.options.inverse ? this.$off : this.$on).before(this.$label).before(this.options.inverse ? this.$on : this.$off); + if (this.options.indeterminate) { + this.$element.prop("indeterminate", true); + } + this._init(); + this._elementHandlers(); + this._handleHandlers(); + this._labelHandlers(); + this._formHandler(); + this._externalLabelHandler(); + this.$element.trigger("init.bootstrapSwitch"); + } + + BootstrapSwitch.prototype._constructor = BootstrapSwitch; + + BootstrapSwitch.prototype.state = function(value, skip) { + if (typeof value === "undefined") { + return this.options.state; + } + if (this.options.disabled || this.options.readonly) { + return this.$element; + } + if (this.options.state && !this.options.radioAllOff && this.$element.is(":radio")) { + return this.$element; + } + if (this.options.indeterminate) { + this.indeterminate(false); + } + value = !!value; + this.$element.prop("checked", value).trigger("change.bootstrapSwitch", skip); + return this.$element; + }; + + BootstrapSwitch.prototype.toggleState = function(skip) { + if (this.options.disabled || this.options.readonly) { + return this.$element; + } + if (this.options.indeterminate) { + this.indeterminate(false); + return this.state(true); + } else { + return this.$element.prop("checked", !this.options.state).trigger("change.bootstrapSwitch", skip); + } + }; + + BootstrapSwitch.prototype.size = function(value) { + if (typeof value === "undefined") { + return this.options.size; + } + if (this.options.size != null) { + this.$wrapper.removeClass("" + this.options.baseClass + "-" + this.options.size); + } + if (value) { + this.$wrapper.addClass("" + this.options.baseClass + "-" + value); + } + this._width(); + this._containerPosition(); + this.options.size = value; + return this.$element; + }; + + BootstrapSwitch.prototype.animate = function(value) { + if (typeof value === "undefined") { + return this.options.animate; + } + value = !!value; + if (value === this.options.animate) { + return this.$element; + } + return this.toggleAnimate(); + }; + + BootstrapSwitch.prototype.toggleAnimate = function() { + this.options.animate = !this.options.animate; + this.$wrapper.toggleClass("" + this.options.baseClass + "-animate"); + return this.$element; + }; + + BootstrapSwitch.prototype.disabled = function(value) { + if (typeof value === "undefined") { + return this.options.disabled; + } + value = !!value; + if (value === this.options.disabled) { + return this.$element; + } + return this.toggleDisabled(); + }; + + BootstrapSwitch.prototype.toggleDisabled = function() { + this.options.disabled = !this.options.disabled; + this.$element.prop("disabled", this.options.disabled); + this.$wrapper.toggleClass("" + this.options.baseClass + "-disabled"); + return this.$element; + }; + + BootstrapSwitch.prototype.readonly = function(value) { + if (typeof value === "undefined") { + return this.options.readonly; + } + value = !!value; + if (value === this.options.readonly) { + return this.$element; + } + return this.toggleReadonly(); + }; + + BootstrapSwitch.prototype.toggleReadonly = function() { + this.options.readonly = !this.options.readonly; + this.$element.prop("readonly", this.options.readonly); + this.$wrapper.toggleClass("" + this.options.baseClass + "-readonly"); + return this.$element; + }; + + BootstrapSwitch.prototype.indeterminate = function(value) { + if (typeof value === "undefined") { + return this.options.indeterminate; + } + value = !!value; + if (value === this.options.indeterminate) { + return this.$element; + } + return this.toggleIndeterminate(); + }; + + BootstrapSwitch.prototype.toggleIndeterminate = function() { + this.options.indeterminate = !this.options.indeterminate; + this.$element.prop("indeterminate", this.options.indeterminate); + this.$wrapper.toggleClass("" + this.options.baseClass + "-indeterminate"); + this._containerPosition(); + return this.$element; + }; + + BootstrapSwitch.prototype.inverse = function(value) { + if (typeof value === "undefined") { + return this.options.inverse; + } + value = !!value; + if (value === this.options.inverse) { + return this.$element; + } + return this.toggleInverse(); + }; + + BootstrapSwitch.prototype.toggleInverse = function() { + var $off, $on; + this.$wrapper.toggleClass("" + this.options.baseClass + "-inverse"); + $on = this.$on.clone(true); + $off = this.$off.clone(true); + this.$on.replaceWith($off); + this.$off.replaceWith($on); + this.$on = $off; + this.$off = $on; + this.options.inverse = !this.options.inverse; + return this.$element; + }; + + BootstrapSwitch.prototype.onColor = function(value) { + var color; + color = this.options.onColor; + if (typeof value === "undefined") { + return color; + } + if (color != null) { + this.$on.removeClass("" + this.options.baseClass + "-" + color); + } + this.$on.addClass("" + this.options.baseClass + "-" + value); + this.options.onColor = value; + return this.$element; + }; + + BootstrapSwitch.prototype.offColor = function(value) { + var color; + color = this.options.offColor; + if (typeof value === "undefined") { + return color; + } + if (color != null) { + this.$off.removeClass("" + this.options.baseClass + "-" + color); + } + this.$off.addClass("" + this.options.baseClass + "-" + value); + this.options.offColor = value; + return this.$element; + }; + + BootstrapSwitch.prototype.onText = function(value) { + if (typeof value === "undefined") { + return this.options.onText; + } + this.$on.html(value); + this._width(); + this._containerPosition(); + this.options.onText = value; + return this.$element; + }; + + BootstrapSwitch.prototype.offText = function(value) { + if (typeof value === "undefined") { + return this.options.offText; + } + this.$off.html(value); + this._width(); + this._containerPosition(); + this.options.offText = value; + return this.$element; + }; + + BootstrapSwitch.prototype.labelText = function(value) { + if (typeof value === "undefined") { + return this.options.labelText; + } + this.$label.html(value); + this._width(); + this.options.labelText = value; + return this.$element; + }; + + BootstrapSwitch.prototype.handleWidth = function(value) { + if (typeof value === "undefined") { + return this.options.handleWidth; + } + this.options.handleWidth = value; + this._width(); + this._containerPosition(); + return this.$element; + }; + + BootstrapSwitch.prototype.labelWidth = function(value) { + if (typeof value === "undefined") { + return this.options.labelWidth; + } + this.options.labelWidth = value; + this._width(); + this._containerPosition(); + return this.$element; + }; + + BootstrapSwitch.prototype.baseClass = function(value) { + return this.options.baseClass; + }; + + BootstrapSwitch.prototype.wrapperClass = function(value) { + if (typeof value === "undefined") { + return this.options.wrapperClass; + } + if (!value) { + value = $.fn.bootstrapSwitch.defaults.wrapperClass; + } + this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(" ")); + this.$wrapper.addClass(this._getClasses(value).join(" ")); + this.options.wrapperClass = value; + return this.$element; + }; + + BootstrapSwitch.prototype.radioAllOff = function(value) { + if (typeof value === "undefined") { + return this.options.radioAllOff; + } + value = !!value; + if (value === this.options.radioAllOff) { + return this.$element; + } + this.options.radioAllOff = value; + return this.$element; + }; + + BootstrapSwitch.prototype.onInit = function(value) { + if (typeof value === "undefined") { + return this.options.onInit; + } + if (!value) { + value = $.fn.bootstrapSwitch.defaults.onInit; + } + this.options.onInit = value; + return this.$element; + }; + + BootstrapSwitch.prototype.onSwitchChange = function(value) { + if (typeof value === "undefined") { + return this.options.onSwitchChange; + } + if (!value) { + value = $.fn.bootstrapSwitch.defaults.onSwitchChange; + } + this.options.onSwitchChange = value; + return this.$element; + }; + + BootstrapSwitch.prototype.destroy = function() { + var $form; + $form = this.$element.closest("form"); + if ($form.length) { + $form.off("reset.bootstrapSwitch").removeData("bootstrap-switch"); + } + this.$container.children().not(this.$element).remove(); + this.$element.unwrap().unwrap().off(".bootstrapSwitch").removeData("bootstrap-switch"); + return this.$element; + }; + + BootstrapSwitch.prototype._width = function() { + var $handles, handleWidth; + $handles = this.$on.add(this.$off); + $handles.add(this.$label).css("width", ""); + handleWidth = this.options.handleWidth === "auto" ? Math.max(this.$on.width(), this.$off.width()) : this.options.handleWidth; + $handles.width(handleWidth); + this.$label.width((function(_this) { + return function(index, width) { + if (_this.options.labelWidth !== "auto") { + return _this.options.labelWidth; + } + if (width < handleWidth) { + return handleWidth; + } else { + return width; + } + }; + })(this)); + this._handleWidth = this.$on.outerWidth(); + this._labelWidth = this.$label.outerWidth(); + this.$container.width((this._handleWidth * 2) + this._labelWidth); + return this.$wrapper.width(this._handleWidth + this._labelWidth); + }; + + BootstrapSwitch.prototype._containerPosition = function(state, callback) { + if (state == null) { + state = this.options.state; + } + this.$container.css("margin-left", (function(_this) { + return function() { + var values; + values = [0, "-" + _this._handleWidth + "px"]; + if (_this.options.indeterminate) { + return "-" + (_this._handleWidth / 2) + "px"; + } + if (state) { + if (_this.options.inverse) { + return values[1]; + } else { + return values[0]; + } + } else { + if (_this.options.inverse) { + return values[0]; + } else { + return values[1]; + } + } + }; + })(this)); + if (!callback) { + return; + } + return setTimeout(function() { + return callback(); + }, 50); + }; + + BootstrapSwitch.prototype._init = function() { + var init, initInterval; + init = (function(_this) { + return function() { + _this._width(); + return _this._containerPosition(null, function() { + if (_this.options.animate) { + return _this.$wrapper.addClass("" + _this.options.baseClass + "-animate"); + } + }); + }; + })(this); + if (this.$wrapper.is(":visible")) { + return init(); + } + return initInterval = window.setInterval((function(_this) { + return function() { + if (_this.$wrapper.is(":visible")) { + init(); + return window.clearInterval(initInterval); + } + }; + })(this), 50); + }; + + BootstrapSwitch.prototype._elementHandlers = function() { + return this.$element.on({ + "change.bootstrapSwitch": (function(_this) { + return function(e, skip) { + var state; + e.preventDefault(); + e.stopImmediatePropagation(); + state = _this.$element.is(":checked"); + _this._containerPosition(state); + if (state === _this.options.state) { + return; + } + _this.options.state = state; + _this.$wrapper.toggleClass("" + _this.options.baseClass + "-off").toggleClass("" + _this.options.baseClass + "-on"); + if (!skip) { + if (_this.$element.is(":radio")) { + $("[name='" + (_this.$element.attr('name')) + "']").not(_this.$element).prop("checked", false).trigger("change.bootstrapSwitch", true); + } + return _this.$element.trigger("switchChange.bootstrapSwitch", [state]); + } + }; + })(this), + "focus.bootstrapSwitch": (function(_this) { + return function(e) { + e.preventDefault(); + return _this.$wrapper.addClass("" + _this.options.baseClass + "-focused"); + }; + })(this), + "blur.bootstrapSwitch": (function(_this) { + return function(e) { + e.preventDefault(); + return _this.$wrapper.removeClass("" + _this.options.baseClass + "-focused"); + }; + })(this), + "keydown.bootstrapSwitch": (function(_this) { + return function(e) { + if (!e.which || _this.options.disabled || _this.options.readonly) { + return; + } + switch (e.which) { + case 37: + e.preventDefault(); + e.stopImmediatePropagation(); + return _this.state(false); + case 39: + e.preventDefault(); + e.stopImmediatePropagation(); + return _this.state(true); + } + }; + })(this) + }); + }; + + BootstrapSwitch.prototype._handleHandlers = function() { + this.$on.on("click.bootstrapSwitch", (function(_this) { + return function(event) { + event.preventDefault(); + event.stopPropagation(); + _this.state(false); + return _this.$element.trigger("focus.bootstrapSwitch"); + }; + })(this)); + return this.$off.on("click.bootstrapSwitch", (function(_this) { + return function(event) { + event.preventDefault(); + event.stopPropagation(); + _this.state(true); + return _this.$element.trigger("focus.bootstrapSwitch"); + }; + })(this)); + }; + + BootstrapSwitch.prototype._labelHandlers = function() { + return this.$label.on({ + "mousedown.bootstrapSwitch touchstart.bootstrapSwitch": (function(_this) { + return function(e) { + if (_this._dragStart || _this.options.disabled || _this.options.readonly) { + return; + } + e.preventDefault(); + e.stopPropagation(); + _this._dragStart = (e.pageX || e.originalEvent.touches[0].pageX) - parseInt(_this.$container.css("margin-left"), 10); + if (_this.options.animate) { + _this.$wrapper.removeClass("" + _this.options.baseClass + "-animate"); + } + return _this.$element.trigger("focus.bootstrapSwitch"); + }; + })(this), + "mousemove.bootstrapSwitch touchmove.bootstrapSwitch": (function(_this) { + return function(e) { + var difference; + if (_this._dragStart == null) { + return; + } + e.preventDefault(); + difference = (e.pageX || e.originalEvent.touches[0].pageX) - _this._dragStart; + if (difference < -_this._handleWidth || difference > 0) { + return; + } + _this._dragEnd = difference; + return _this.$container.css("margin-left", "" + _this._dragEnd + "px"); + }; + })(this), + "mouseup.bootstrapSwitch touchend.bootstrapSwitch": (function(_this) { + return function(e) { + var state; + if (!_this._dragStart) { + return; + } + e.preventDefault(); + if (_this.options.animate) { + _this.$wrapper.addClass("" + _this.options.baseClass + "-animate"); + } + if (_this._dragEnd) { + state = _this._dragEnd > -(_this._handleWidth / 2); + _this._dragEnd = false; + _this.state(_this.options.inverse ? !state : state); + } else { + _this.state(!_this.options.state); + } + return _this._dragStart = false; + }; + })(this), + "mouseleave.bootstrapSwitch": (function(_this) { + return function(e) { + return _this.$label.trigger("mouseup.bootstrapSwitch"); + }; + })(this) + }); + }; + + BootstrapSwitch.prototype._externalLabelHandler = function() { + var $externalLabel; + $externalLabel = this.$element.closest("label"); + return $externalLabel.on("click", (function(_this) { + return function(event) { + event.preventDefault(); + event.stopImmediatePropagation(); + if (event.target === $externalLabel[0]) { + return _this.toggleState(); + } + }; + })(this)); + }; + + BootstrapSwitch.prototype._formHandler = function() { + var $form; + $form = this.$element.closest("form"); + if ($form.data("bootstrap-switch")) { + return; + } + return $form.on("reset.bootstrapSwitch", function() { + return window.setTimeout(function() { + return $form.find("input").filter(function() { + return $(this).data("bootstrap-switch"); + }).each(function() { + return $(this).bootstrapSwitch("state", this.checked); + }); + }, 1); + }).data("bootstrap-switch", true); + }; + + BootstrapSwitch.prototype._getClasses = function(classes) { + var c, cls, _i, _len; + if (!$.isArray(classes)) { + return ["" + this.options.baseClass + "-" + classes]; + } + cls = []; + for (_i = 0, _len = classes.length; _i < _len; _i++) { + c = classes[_i]; + cls.push("" + this.options.baseClass + "-" + c); + } + return cls; + }; + + return BootstrapSwitch; + + })(); + $.fn.bootstrapSwitch = function() { + var args, option, ret; + option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + ret = this; + this.each(function() { + var $this, data; + $this = $(this); + data = $this.data("bootstrap-switch"); + if (!data) { + $this.data("bootstrap-switch", data = new BootstrapSwitch(this, option)); + } + if (typeof option === "string") { + return ret = data[option].apply(data, args); + } + }); + return ret; + }; + $.fn.bootstrapSwitch.Constructor = BootstrapSwitch; + return $.fn.bootstrapSwitch.defaults = { + state: true, + size: null, + animate: true, + disabled: false, + readonly: false, + indeterminate: false, + inverse: false, + radioAllOff: false, + onColor: "primary", + offColor: "default", + onText: "ON", + offText: "OFF", + labelText: " ", + handleWidth: "auto", + labelWidth: "auto", + baseClass: "bootstrap-switch", + wrapperClass: "wrapper", + onInit: function() {}, + onSwitchChange: function() {} + }; + })(window.jQuery, window); + +}).call(this); diff --git a/style/bootstrap-switch.css b/style/bootstrap-switch.css new file mode 100644 index 00000000..cea4acb8 --- /dev/null +++ b/style/bootstrap-switch.css @@ -0,0 +1,196 @@ +/* ======================================================================== + * bootstrap-switch - v3.3.2 + * http://www.bootstrap-switch.org + * ======================================================================== + * Copyright 2012-2013 Mattia Larentis + * + * ======================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== + */ + +.bootstrap-switch { + display: inline-block; + direction: ltr; + cursor: pointer; + border-radius: 4px; + border: 1px solid; + border-color: #cccccc; + position: relative; + text-align: left; + overflow: hidden; + line-height: 8px; + z-index: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: middle; + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.bootstrap-switch .bootstrap-switch-container { + display: inline-block; + top: 0; + border-radius: 4px; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.bootstrap-switch .bootstrap-switch-handle-on, +.bootstrap-switch .bootstrap-switch-handle-off, +.bootstrap-switch .bootstrap-switch-label { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; + display: inline-block !important; + height: 100%; + padding: 6px 12px; + font-size: 14px; + line-height: 20px; +} +.bootstrap-switch .bootstrap-switch-handle-on, +.bootstrap-switch .bootstrap-switch-handle-off { + text-align: center; + z-index: 1; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary { + color: #fff; + background: #428bca; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info { + color: #fff; + background: #5bc0de; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success { + color: #fff; + background: #5cb85c; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning { + background: #f0ad4e; + color: #fff; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger { + color: #fff; + background: #d9534f; +} +.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default, +.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default { + color: #000; + background: #eeeeee; +} +.bootstrap-switch .bootstrap-switch-label { + text-align: center; + margin-top: -1px; + margin-bottom: -1px; + z-index: 100; + color: #333333; + background: #ffffff; +} +.bootstrap-switch .bootstrap-switch-handle-on { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.bootstrap-switch .bootstrap-switch-handle-off { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch input[type='radio'], +.bootstrap-switch input[type='checkbox'] { + position: absolute !important; + top: 0; + left: 0; + opacity: 0; + filter: alpha(opacity=0); + z-index: -1; +} +.bootstrap-switch input[type='radio'].form-control, +.bootstrap-switch input[type='checkbox'].form-control { + height: auto; +} +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label { + padding: 6px 16px; + font-size: 18px; + line-height: 1.33; +} +.bootstrap-switch.bootstrap-switch-disabled, +.bootstrap-switch.bootstrap-switch-readonly, +.bootstrap-switch.bootstrap-switch-indeterminate { + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off, +.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default !important; +} +.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container { + -webkit-transition: margin-left 0.5s; + transition: margin-left 0.5s; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-focused { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label, +.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} diff --git a/style/categories.json b/style/categories.json new file mode 100644 index 00000000..97b76eac --- /dev/null +++ b/style/categories.json @@ -0,0 +1,7 @@ +{ + "cities":"tower", + "content":"th", + "settings":"cog", + "status":"tasks", + "users":"user" +} \ No newline at end of file diff --git a/style/default.css b/style/default.css index ebbe3618..72f82823 100644 --- a/style/default.css +++ b/style/default.css @@ -176,6 +176,10 @@ body { padding: 5px; } +.slx-bold { + font-weight: bold; +} + .slx-fade { opacity: 0.5; } @@ -241,4 +245,190 @@ input[readonly] { border-top-right-radius: 0px; margin: 0px; padding: 19px; -} \ No newline at end of file +} + + + +/* + * Base structure + */ + + + +/* + * Global add-ons + */ + +.sub-header { + padding-bottom: 10px; + border-bottom: 1px solid #eee; +} + +/* + * Top navigation + * Hide default border to remove 1px line. + */ +.navbar-fixed-top { + border: 0; +} + +/* + * Sidebar + */ + +/* Hide for mobile, show later */ +.sidebar { + display: none; +} +@media (min-width: 768px) { + .sidebar { + position: fixed; + top: 51px; + bottom: 0; + left: 0; + z-index: 1000; + display: block; + padding: 20px; + padding-top: 8px; + overflow-x: hidden; + overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ + background-color: #373d47; + } +} + +/* Sidebar navigation */ +.nav-sidebar { + margin-right: -21px; /* 20px padding + 1px border */ + margin-left: -20px; +} +.nav-sidebar > li > a { + padding: 7px; + padding-right: 20px; + padding-left: 20px; + color: #CCCCCC; +} +.nav-sidebar > .active > a, +.nav-sidebar > .active > a:hover, +.nav-sidebar > .active > a:focus { + color: #FFFFFF; + background-color: #24272d; +} +.nav-sidebar > li > a:hover, +.nav-sidebar > li > a:focus { + background-color: #2C323D; +} + + +/* + * + * Dashboard custom + * + * Main content + */ + +.main { + padding: 20px; +} +@media (min-width: 768px) { + .main { + padding-right: 40px; + padding-left: 40px; + } +} +.main .page-header { + margin-top: 0; +} + + +/* + * Placeholder dashboard ideas + */ + +.placeholders { + margin-bottom: 30px; + text-align: center; +} +.placeholders h4 { + margin-bottom: 0; +} +.placeholder { + margin-bottom: 20px; +} +.placeholder img { + display: inline-block; + border-radius: 50%; +} + +.dash-header { + padding-top: 5px; + padding-left: 10px; + padding-bottom: 5px; + font-size: 17px; + margin-right: -21px; + margin-left: -20px; + color: #FFFFFF; +} + +/* + * Sysconfig Module Editor + */ + +.mod-nav{ + width: 250px; + float: left; + margin-right: 4px; + border-right: solid 1px #DDD; + padding: 4px; + height: 545px; + overflow: auto; +} + +.item { + padding: 4px; + margin: 3px 0; + border-radius: 3px; +} + +.item:HOVER { + background-color: #EEE; + cursor: pointer; +} + +.item-link { + color: #5893C6; +} + +.item-lock { + color: #939393; +} + +.dir-icon { + color: #2E6DA4; +} + +.folder { + padding-left: 16px; + display: none; + border-left: dashed 1px #CCC; +} + +#editor-header{ + display: block; + float: none; + width: 875px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.mod-editor{ + display: block; + float: none; + resize: none; + width: 875px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +textarea.form-control .editor-box{ + height: 520px; +} diff --git a/templates/backup/_page.html b/templates/backup/_page.html deleted file mode 100644 index 47b5a174..00000000 --- a/templates/backup/_page.html +++ /dev/null @@ -1,41 +0,0 @@ -

{{lang_backupRestore}}

- -
- - -
-
{{lang_backup}}
-
-

{{lang_backupDescription}}

- -
-
-
- -
- - -
-
{{lang_restore}}
-
-

{{lang_restoreDescription}}

-
- - - - {{lang_browseForFile}}… - - -
-
- -

{{lang_systemExplanation}}

-
-
- -

{{lang_dozmodExplanation}}

-
- -
-
-
\ No newline at end of file diff --git a/templates/backup/restore.html b/templates/backup/restore.html deleted file mode 100644 index e7dadae3..00000000 --- a/templates/backup/restore.html +++ /dev/null @@ -1,61 +0,0 @@ -
-
{{lang_backup}}
-
-
-
{{lang_stopping}} dmsd
-
{{lang_stopping}} ldadp
-
{{lang_stopping}} vmstore
-
{{lang_restoreConfig}}
-
{{lang_reboot}}
-
- - -
-
- - diff --git a/templates/baseconfig/_page.html b/templates/baseconfig/_page.html deleted file mode 100644 index 9bea7206..00000000 --- a/templates/baseconfig/_page.html +++ /dev/null @@ -1,42 +0,0 @@ -

{{lang_basicConfiguration}}

-

{{lang_clientRelatedConfig}}

-
- - - {{#categories}} -
-
{{category_name}}
-
- {{#settings}} -
-
-
- {{setting}} -
{{defaultvalue}}
-
-
- {{{item}}} -
-
- -
-
-
- - {{/settings}} -
-
- {{/categories}} - - - - Download -
diff --git a/templates/dialog-generic.html b/templates/dialog-generic.html deleted file mode 100644 index 5face8ce..00000000 --- a/templates/dialog-generic.html +++ /dev/null @@ -1,13 +0,0 @@ - \ No newline at end of file diff --git a/templates/dozmod/images-delete.html b/templates/dozmod/images-delete.html deleted file mode 100644 index c4cbfd34..00000000 --- a/templates/dozmod/images-delete.html +++ /dev/null @@ -1,57 +0,0 @@ -

{{lang_heading}}

- -
-
- {{lang_subHeading}} -
-
-

{{lang_description}}

-
-
- - - - - - - - - - - - - - - {{#images}} - - - - - - - - - {{/images}} - -
{{lang_image}}{{lang_version}}{{lang_owner}}{{lang_size}}
{{displayname}}
{{imageversionid}}
{{version}}{{lastname}}, {{firstname}}{{filesize}}
- -
- -
-
-
- - \ No newline at end of file diff --git a/templates/dozmod/mailconfig.html b/templates/dozmod/mailconfig.html deleted file mode 100644 index b19776c0..00000000 --- a/templates/dozmod/mailconfig.html +++ /dev/null @@ -1,91 +0,0 @@ -

{{lang_mailConfigHeadline}}

- -
-
- {{lang_mailConfig}} -
-
-

{{lang_mailDescription}}

-

[BETA] Diese FunktionalitÃĪt ist neu. Wir bitten um Nachsicht, falls es Situationen gibt, in denen zu viele - oder zu wenige Nachrichten verschickt werden.

-
- - -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-

{{lang_asteriskRequired}}

-
-

{{lang_testConfiguration}}

-
- - -
-
- - - - -
- - -
-
-
- - \ No newline at end of file diff --git a/templates/dozmod/orglist.html b/templates/dozmod/orglist.html deleted file mode 100644 index d325cc4d..00000000 --- a/templates/dozmod/orglist.html +++ /dev/null @@ -1,51 +0,0 @@ -

{{lang_organizationList}}

- -
-
- {{lang_organizationListHeader}} -
-
-
- - - - - - - - - {{#organizations}} - - - - - {{/organizations}} - -
{{lang_organization}}
{{displayname}}
-
-
-
- - \ No newline at end of file diff --git a/templates/dozmod/userlist.html b/templates/dozmod/userlist.html deleted file mode 100644 index a76eae5e..00000000 --- a/templates/dozmod/userlist.html +++ /dev/null @@ -1,62 +0,0 @@ -

{{lang_userList}}

- -
-
- {{lang_userListHeader}} -
-
-

{{lang_userListDescription}}

-
- - - - - - - - - - - - - - {{#users}} - - - - - - - - - - {{/users}} - -
{{lang_user}}{{lang_organization}}{{lang_lastLogin}}{{lang_email}}
{{lastname}}, {{firstname}}{{orgname}}{{lastlogin}}{{email}}
-
-
-
- - \ No newline at end of file diff --git a/templates/eventlog/_page.html b/templates/eventlog/_page.html deleted file mode 100644 index 2e657805..00000000 --- a/templates/eventlog/_page.html +++ /dev/null @@ -1,41 +0,0 @@ -

{{lang_eventLog}}

-{{{pagenav}}} - - - - - - - - - {{#list}} - - - - - - - {{/list}} - -
{{lang_when}}{{lang_event}}{{lang_details}}
{{date}}{{description}}{{#extra}} - » - - {{/extra}}
-{{{pagenav}}} - - diff --git a/templates/footer.html b/templates/footer.html deleted file mode 100644 index 8cf71a5c..00000000 --- a/templates/footer.html +++ /dev/null @@ -1,2 +0,0 @@ -
- \ No newline at end of file diff --git a/templates/internetaccess/_page.html b/templates/internetaccess/_page.html deleted file mode 100644 index a2aaddac..00000000 --- a/templates/internetaccess/_page.html +++ /dev/null @@ -1,40 +0,0 @@ -

{{lang_internetAccess}}

- -
- - - -
-
{{lang_internetAccess}}
-
-

{{lang_description}}

-
- {{lang_proxyType}} - -
-
-

{{lang_manualProxyConfig}}

-
- {{lang_proxyAddress}} * - -
-
- {{lang_proxyPort}} * - -
-
- {{lang_proxyUsername}} - -
-
- {{lang_proxyPassword}} - -
- -
-
-
diff --git a/templates/internetaccess/restart.html b/templates/internetaccess/restart.html deleted file mode 100644 index effe1feb..00000000 --- a/templates/internetaccess/restart.html +++ /dev/null @@ -1,22 +0,0 @@ -
-
{{lang_serviceRestart}}
-
-
{{lang_restarting}} syncdaemon
-
{{lang_restarting}} dmsd
-
{{lang_restarting}} ldadp
- -
-
- - diff --git a/templates/locations/location-subnets.html b/templates/locations/location-subnets.html deleted file mode 100644 index 76b7442a..00000000 --- a/templates/locations/location-subnets.html +++ /dev/null @@ -1,73 +0,0 @@ -
-
{{lang_locationSettings}}
-
- - - -
- -
-
-
-
- {{lang_name}} - -
-
-
-
- {{lang_parentLocation}} - -
-
-
-
-
- - -
-
-
-
-
{{lang_assignedSubnets}}
-
{{lang_assignSubnetExplanation}}
- - - - - - - - {{#list}} - - - - - - - {{/list}} - - - -
#{{lang_startAddress}}{{lang_endAddress}}
{{subnetid}}
- - - - -
-
-
-
{{lang_locationInfo}}
-
- {{lang_referencingLectures}}: {{lectures}} -
- -
\ No newline at end of file diff --git a/templates/locations/locations.html b/templates/locations/locations.html deleted file mode 100644 index 76c8f97c..00000000 --- a/templates/locations/locations.html +++ /dev/null @@ -1,96 +0,0 @@ -
- -

{{lang_locationsMainHeading}}

- - - - - - - {{#list}} - - - - - - {{/list}} -
#{{lang_locationName}}
{{locationid}}
{{locationname}}
- {{lang_edit}} -
-
- - - - - - - - -
- - - -
-
-
- diff --git a/templates/locations/subnets.html b/templates/locations/subnets.html deleted file mode 100644 index 2294f42b..00000000 --- a/templates/locations/subnets.html +++ /dev/null @@ -1,35 +0,0 @@ -
- -

{{lang_listOfSubnets}}

-
- - - - - - - - - - {{#list}} - - - - - - - {{/list}} -
#{{lang_startAddress}}{{lang_endAddress}}{{lang_location}}
{{subnetid}} - -
-
- -
-
-
diff --git a/templates/main-menu.html b/templates/main-menu.html deleted file mode 100644 index 7852dd39..00000000 --- a/templates/main-menu.html +++ /dev/null @@ -1,83 +0,0 @@ - - - diff --git a/templates/messagebox-error.html b/templates/messagebox-error.html deleted file mode 100644 index 63f59a96..00000000 --- a/templates/messagebox-error.html +++ /dev/null @@ -1 +0,0 @@ -
{{{message}}}
diff --git a/templates/messagebox-info.html b/templates/messagebox-info.html deleted file mode 100644 index 7136298c..00000000 --- a/templates/messagebox-info.html +++ /dev/null @@ -1 +0,0 @@ -
{{{message}}}
diff --git a/templates/messagebox-success.html b/templates/messagebox-success.html deleted file mode 100644 index 3fa263ef..00000000 --- a/templates/messagebox-success.html +++ /dev/null @@ -1 +0,0 @@ -
{{{message}}}
diff --git a/templates/messagebox-warning.html b/templates/messagebox-warning.html deleted file mode 100644 index 48a95b4d..00000000 --- a/templates/messagebox-warning.html +++ /dev/null @@ -1 +0,0 @@ -
{{{message}}}
diff --git a/templates/minilinux/download.html b/templates/minilinux/download.html deleted file mode 100644 index 2e32df5a..00000000 --- a/templates/minilinux/download.html +++ /dev/null @@ -1 +0,0 @@ -
{{name}}
\ No newline at end of file diff --git a/templates/minilinux/filelist.html b/templates/minilinux/filelist.html deleted file mode 100644 index ca94f4d0..00000000 --- a/templates/minilinux/filelist.html +++ /dev/null @@ -1,77 +0,0 @@ - {{#systems}} -
-
-

{{title}}

-
-
-
- {{lang_desiredVersion}} - -
- {{#systemChanged}} -

- {{lang_canUpdate1}} {{title}} {{lang_canUpdate2}} -

-

{{lang_update}}

- {{/systemChanged}} - {{^systemChanged}} -

{{lang_systemUpdated}}

- {{/systemChanged}} -
-

{{lang_filesInVersion}} {{version}}

-
    - {{#files}} -
  • -
    -
    {{name}}
    -
    - {{^fileChanged}} {{lang_actual}}{{/fileChanged}} - {{#fileChanged}} {{lang_outdated}}{{/fileChanged}} -
    -
    - {{#fileChanged}}{{lang_update}}{{/fileChanged}} - {{^fileChanged}}{{lang_redownload}}{{/fileChanged}} -
    -
    - {{{download}}} -
  • - {{/files}} -
-
-
- {{/systems}} - {{^systems}} -
{{lang_configurationPackageNotFound}}
- {{/systems}} - - diff --git a/templates/page-adduser.html b/templates/page-adduser.html deleted file mode 100644 index 0b097890..00000000 --- a/templates/page-adduser.html +++ /dev/null @@ -1,28 +0,0 @@ -
- - - -
-
{{lang_username}} *
-
-
-
-
{{lang_password}} *
-
-
-
-
-
{{lang_fullName}} *
-
-
-
-
{{lang_telephone}}
-
-
-
-
E-Mail
-
-
- - -
\ No newline at end of file diff --git a/templates/page-login.html b/templates/page-login.html deleted file mode 100644 index 247e9a55..00000000 --- a/templates/page-login.html +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/templates/page-main-guest.html b/templates/page-main-guest.html deleted file mode 100644 index 8f3051d5..00000000 --- a/templates/page-main-guest.html +++ /dev/null @@ -1,13 +0,0 @@ -
-

{{lang_welcome}}

-

{{lang_introGuest}}

- {{#register}} - - {{/register}} -

{{lang_login}} »

-
diff --git a/templates/page-main.html b/templates/page-main.html deleted file mode 100644 index 64264a5d..00000000 --- a/templates/page-main.html +++ /dev/null @@ -1,35 +0,0 @@ -
-

{{lang_welcome}}, {{user}}

-

{{lang_intro}}

-
- diff --git a/templates/page-minilinux.html b/templates/page-minilinux.html deleted file mode 100644 index dc13e6b0..00000000 --- a/templates/page-minilinux.html +++ /dev/null @@ -1,14 +0,0 @@ -
-
{{lang_listObtained}}
-
- - \ No newline at end of file diff --git a/templates/page-news.html b/templates/page-news.html deleted file mode 100644 index 8e400498..00000000 --- a/templates/page-news.html +++ /dev/null @@ -1,57 +0,0 @@ -
-
- {{lang_editNews}} -
-
-

{{lang_newsIntro}}

-
-
- - -
-
- - -
-

{{lang_latestUpdate}}: {{latestDate}}

- - -
-
-
- -
-
- {{lang_newsOld}} -
-
-
-
- - - - - - - - - - - - {{#list}} - - - - - - - {{/list}} - -
{{lang_date}}{{lang_title}}{{lang_content}}
{{date}}{{title}}{{content}} - {{lang_show}} - -
-
-
-
-
diff --git a/templates/page-syslog.html b/templates/page-syslog.html deleted file mode 100644 index 98e94291..00000000 --- a/templates/page-syslog.html +++ /dev/null @@ -1,58 +0,0 @@ -

{{lang_clientLog}}

-
- -
- {{lang_filter}} - - - {{lang_not}} - - - - -
-
-{{{pagenav}}} - - - - - - - - - - {{#list}} - - - - - - - - {{/list}} - -
{{lang_when}}{{lang_client}}{{lang_event}}{{lang_details}}
{{date}}{{clientip}}{{description}}{{#extra}} - » - - {{/extra}}
-{{{pagenav}}} - - - - diff --git a/templates/page-vmstore.html b/templates/page-vmstore.html deleted file mode 100644 index fe2c5225..00000000 --- a/templates/page-vmstore.html +++ /dev/null @@ -1,111 +0,0 @@ -
- - - - -
-
- {{lang_vmLocation}} -
-
-

{{lang_vmLocationChoose}}

-
-
- {{lang_intern}} -
-
- {{lang_noAdditionalInformation}} -
-
-
-
- NFS - -
-
- - -
-
-
-
- CIFS -
-
- - -
- -
- - {{lang_username}} - - - - {{lang_password}} - - -
-
- -
- - {{lang_username}} - - - - {{lang_password}} - - -
-
-
- -
-
-
- - - - diff --git a/templates/pagenav.html b/templates/pagenav.html deleted file mode 100644 index 93194999..00000000 --- a/templates/pagenav.html +++ /dev/null @@ -1,16 +0,0 @@ -
    - {{#pages}} - {{#current}} -
  • {{text}} (current)
  • - {{/current}} - {{^current}} - {{#text}} -
  • {{text}}
  • - {{/text}} - {{^text}} -
  • - {{/text}} - {{/current}} - {{/pages}} -
-
\ No newline at end of file diff --git a/templates/serversetup/ipaddress.html b/templates/serversetup/ipaddress.html deleted file mode 100644 index 0b3b2ed7..00000000 --- a/templates/serversetup/ipaddress.html +++ /dev/null @@ -1,34 +0,0 @@ -
-
- {{lang_bootAddress}} -
-
-
- {{lang_chooseIP}} -
-
- - - - {{#ips}} - - - {{#default}} - - {{/default}} - {{^default}} - - {{/default}} - - {{/ips}} -
{{ip}} - {{lang_active}} - - -
-

- {{lang_bootHint}} -

-
-
-
\ No newline at end of file diff --git a/templates/serversetup/ipxe.html b/templates/serversetup/ipxe.html deleted file mode 100644 index 4539624b..00000000 --- a/templates/serversetup/ipxe.html +++ /dev/null @@ -1,70 +0,0 @@ -
- - - - -
-
- {{lang_bootMenu}} -
-
-

- {{lang_bootInfo}} -

-
- -
- {{lang_bootBehavior}} -
-
-
-
- -
- {{lang_menuDisplayTime}} -
- - {{lang_seconds}} -
-
- -
- {{lang_masterPassword}} -
- -
- {{lang_masterPasswordHelp}} -
- -
- {{lang_menuCustom}} - -
-
- - -
-
- - diff --git a/templates/serversetup/ipxe_update.html b/templates/serversetup/ipxe_update.html deleted file mode 100644 index 9c598667..00000000 --- a/templates/serversetup/ipxe_update.html +++ /dev/null @@ -1,20 +0,0 @@ -
-
{{lang_menuGeneration}}
-
-
{{lang_menuGeneration}}
- -
-
- - diff --git a/templates/statistics/clientlist.html b/templates/statistics/clientlist.html deleted file mode 100644 index 8e8565fe..00000000 --- a/templates/statistics/clientlist.html +++ /dev/null @@ -1,45 +0,0 @@ -

{{lang_clientList}}

-
{{filter}} ~= {{argument}}
-
- - - - - - - - - - - - {{#rows}} - - - - - - - - - - {{/rows}} -
{{lang_machine}}{{lang_address}}{{lang_lastSeen}}{{lang_kvmSupport}}{{lang_gbRam}}{{lang_tmpGb}}{{lang_cpuModel}}
- {{#hasnotes}}{{/hasnotes}} - {{#state_off}} - - {{/state_off}} - {{#state_idle}} - - {{/state_idle}} - {{#state_occupied}} - - {{/state_occupied}} - {{hostname}} -
{{machineuuid}}
-
{{subnet}}{{lastoctet}}
{{macaddr}}
{{lastseen}}{{kvmstate}}{{gbram}} GiB - {{gbtmp}} GiB - {{#badsectors}}
- - {{badsectors}} -
{{/badsectors}} -
{{lang_realCores}}: {{realcores}}
{{cpumodel}}
diff --git a/templates/statistics/cpumodels.html b/templates/statistics/cpumodels.html deleted file mode 100644 index 2f24cd92..00000000 --- a/templates/statistics/cpumodels.html +++ /dev/null @@ -1,51 +0,0 @@ -
-
-
- {{lang_modelStats}} -
-
-
-
- - - - - - - {{#rows}} - - - - - - {{/rows}} -
{{lang_modelName}}{{lang_cpuCores}}{{lang_modelCount}}
- {{systemmodel}} - {{cores}}{{count}}
-
-
- - -
-
-
-
-
diff --git a/templates/statistics/id44.html b/templates/statistics/id44.html deleted file mode 100644 index 730839b1..00000000 --- a/templates/statistics/id44.html +++ /dev/null @@ -1,48 +0,0 @@ -
-
-
- {{lang_tempPartStats}} -
-
-
-
- - - - - - {{#rows}} - - - - - {{/rows}} -
{{lang_partitionSize}}{{lang_machineCount}}
{{gb}} GiB{{count}}
-
-
- - -
-
-
-
-
\ No newline at end of file diff --git a/templates/statistics/kvmstate.html b/templates/statistics/kvmstate.html deleted file mode 100644 index 107a34f7..00000000 --- a/templates/statistics/kvmstate.html +++ /dev/null @@ -1,47 +0,0 @@ -
-
-
- {{lang_kvmStats}} -
-
-
-
- - - - - - {{#rows}} - - - - - {{/rows}} -
{{lang_kvmState}}{{lang_machineCount}}
{{kvmstate}}{{count}}
-
-
- - -
-
-
-
-
\ No newline at end of file diff --git a/templates/statistics/machine-hdds.html b/templates/statistics/machine-hdds.html deleted file mode 100644 index fd6cf1be..00000000 --- a/templates/statistics/machine-hdds.html +++ /dev/null @@ -1,67 +0,0 @@ -

{{lang_hdds}}

-
- {{#hdds}} -
-
-
- {{s_ModelFamily}} {{dev}} -
-
- {{#s_DeviceModel}} -
{{lang_modelNo}}: {{s_DeviceModel}}, {{lang_serialNo}}: {{s_SerialNumber}}
- {{/s_DeviceModel}} - {{#s_ReallocatedSectorCt}} -
{{lang_reallocatedSectors}}: {{s_ReallocatedSectorCt}}
- {{/s_ReallocatedSectorCt}} - {{#s_CurrentPendingSector}} -
{{lang_pendingSectors}}: {{s_CurrentPendingSector}}
- {{/s_CurrentPendingSector}} - {{#s_PowerOnHours}} -
{{lang_powerOnTime}}: {{s_PowerOnHours}} {{lang_hours}} ({{PowerOnTime}})
- {{/s_PowerOnHours}} -
-
- - - - - - - {{#partitions}} - - - - - - {{/partitions}} -
{{lang_partName}}{{lang_partSize}}{{lang_partType}}
{{name}}{{size}} GiB{{type}}
-
{{lang_total}}: {{size}} GiB
-
-
- - -
-
-
-
-
- {{/hdds}} -
\ No newline at end of file diff --git a/templates/statistics/machine-main.html b/templates/statistics/machine-main.html deleted file mode 100644 index 8071416a..00000000 --- a/templates/statistics/machine-main.html +++ /dev/null @@ -1,124 +0,0 @@ -

- {{hostname}} {{#hostname}}–{{/hostname}} {{clientip}} - {{#notes}}{{/notes}} -

- -
-
-
-
- {{lang_machineSummary}} -
-
- - - - - - - - - - - - - - {{#hostname}} - - - - - {{/hostname}} - - - - - - - - - - - - - - - - -
{{lang_uuid}}{{machineuuid}}
{{lang_macAddr}}{{macaddr}}
{{lang_ip}}{{clientip}}
{{lang_hostname}}{{hostname}}
{{lang_firstSeen}}{{firstseen_s}}
{{lang_lastBoot}}{{lastboot_s}}
{{lang_lastSeen}}{{lastseen_s}}
{{lang_usageState}} - {{#state_off}} - {{lang_machineOff}} - {{/state_off}} - {{#state_idle}} - {{lang_machineIdle}} - {{/state_idle}} - {{#state_occupied}} - {{#username}} - {{lang_machineOccupiedBy}} {{username}} - {{/username}} - {{^username}} - {{lang_machineOccupied}} - {{/username}} -
{{logintime_s}}
- {{/state_occupied}} - {{#session}} -
{{session}}
- {{/session}} -
-
-
-
-
-
-
- {{lang_hardwareSummary}} -
-
- - - - - - - - - - - - - - {{#extram}} - - - - - {{/extram}} - - - - - - - - -
{{lang_cpuModel}} - {{cpumodel}} - {{#Sockets}} -
- {{lang_sockets}}: {{Sockets}}, {{lang_cores}}: {{Realcores}}, {{lang_virtualCores}}: {{Virtualcores}} -
- {{/Sockets}} -
{{lang_model}}{{pcmodel}} ({{manufacturer}})
{{lang_ram}} - {{gbram}} GiB - {{#maxram}}({{lang_maximumAbbrev}} {{maxram}}){{/maxram}} - {{ramtype}} -
{{lang_ramSlots}} - {{ramslotcount}}: - {{#ramslot}} - [ {{size}} ] - {{/ramslot}} -
{{lang_tempPart}}{{gbtmp}} GiB
{{lang_64bitSupport}}{{kvmstate}}
-
-
-
-
diff --git a/templates/statistics/machine-notes.html b/templates/statistics/machine-notes.html deleted file mode 100644 index c4f97543..00000000 --- a/templates/statistics/machine-notes.html +++ /dev/null @@ -1,17 +0,0 @@ - -

{{lang_notes}}

-
-
-
-
-
- - - - - -
-
-
-
-
\ No newline at end of file diff --git a/templates/statistics/machine-usage.html b/templates/statistics/machine-usage.html deleted file mode 100644 index ffaa747b..00000000 --- a/templates/statistics/machine-usage.html +++ /dev/null @@ -1,51 +0,0 @@ -
-
-
-
- {{lang_usageDetails}} -
-
-
-
- - - - - - - {{#rows}} - - - - - - {{/rows}} -
TypeWhenLength
{{from}}{{duration}}
-
-
- - {{#hasrows2}} - - - - - - {{/hasrows2}} - {{#rows2}} - - - - - - {{/rows2}} -
TypeWhenLength
{{from}}{{duration}}
-
-
-
 {{{graph}}}
-
- {{lang_timebarDesc}} -
-
-
-
-
diff --git a/templates/statistics/memory.html b/templates/statistics/memory.html deleted file mode 100644 index f4d2ad24..00000000 --- a/templates/statistics/memory.html +++ /dev/null @@ -1,47 +0,0 @@ -
-
-
- {{lang_memoryStats}} -
-
-
-
- - - - - - {{#rows}} - - - - - {{/rows}} -
{{lang_ramSize}}{{lang_machineCount}}
{{gb}} GiB{{count}}
-
-
- - -
-
-
-
-
\ No newline at end of file diff --git a/templates/statistics/newclients.html b/templates/statistics/newclients.html deleted file mode 100644 index 0d9c74df..00000000 --- a/templates/statistics/newclients.html +++ /dev/null @@ -1,44 +0,0 @@ -
-
-
- {{lang_newMachines}} -
-
- - - - - - - - - {{#rows}} - - - - - - - - {{/rows}} - {{#openbutton}} - - - - {{/openbutton}} -
{{lang_machine}}64BitRAMHDD
{{hostname}}{{firstseen}}{{kvmicon}}{{gbram}} GiB{{gbtmp}} GiB
- - - - - - -
-
-
-
\ No newline at end of file diff --git a/templates/statistics/summary.html b/templates/statistics/summary.html deleted file mode 100644 index 5f16fd89..00000000 --- a/templates/statistics/summary.html +++ /dev/null @@ -1,33 +0,0 @@ -
-
-
-
- {{lang_knownMachines}}: {{known}}  - {{lang_onlineMachines}}: {{online}}  - {{lang_inUseMachines}}: {{used}} ({{usedpercent}}%) -
- {{#badhdd}} - - {{/badhdd}} -
-
-
- - -
-
- diff --git a/templates/statistics/syslog.html b/templates/statistics/syslog.html deleted file mode 100644 index c82cb8ac..00000000 --- a/templates/statistics/syslog.html +++ /dev/null @@ -1,43 +0,0 @@ -

{{lang_logHeadline}}

- - - - - - - - - {{#list}} - - - - - - - {{/list}} - -
{{lang_when}}{{lang_event}}{{lang_details}}
{{date}}{{description}}{{#extra}} - » - - {{/extra}}
- -
- - - - diff --git a/templates/sysconfig/_page.html b/templates/sysconfig/_page.html deleted file mode 100644 index 1a2f64d6..00000000 --- a/templates/sysconfig/_page.html +++ /dev/null @@ -1,227 +0,0 @@ -
-
-
-
- {{lang_availableSystem}} - -
-
-
- - - - {{#configs}} - - - - - - - {{/configs}} -
-
{{config}}
-
- {{^current}} - - {{/current}} - {{#current}} - - - {{lang_active}} - - {{/current}} - - - - - -
- {{^configs}} -
- {{lang_systemConfigurationNotFound}} -
- {{^modules}} -
- {{lang_systemConfigurationAlert}} -
- {{/modules}} - {{/configs}} -
-
- {{#havemodules}} - - {{/havemodules}} -
-
- -
-
-
- {{lang_availableModules}} - -
-
-
- - - - {{#modules}} - - - - - - - {{/modules}} -
{{moduletype}}
{{module}}
- {{#iscustom}} - - - - {{/iscustom}} - - - - -
- {{^modules}} -
{{lang_configurationModuleNotFound}}
- {{/modules}} -
-
- -
-
-
- -
-
{{lang_legend}}
-
-

- - {{lang_showLong}} -

-

- - {{lang_downloadLong}} -

-

- - {{lang_rebuildLong}} -

-

- - {{lang_rebuildOutdatedLong}} -

-

- - {{lang_editLong}} -

-
- - {{lang_deleteLong}} -
-
-
- - - - - - \ No newline at end of file diff --git a/templates/sysconfig/ad-finish.html b/templates/sysconfig/ad-finish.html deleted file mode 100644 index f73cad9d..00000000 --- a/templates/sysconfig/ad-finish.html +++ /dev/null @@ -1,29 +0,0 @@ -

- {{lang_adStarted}} -

- -
-
{{lang_generateModule}}
-
-
- - - diff --git a/templates/sysconfig/ad-selfsearch.html b/templates/sysconfig/ad-selfsearch.html deleted file mode 100644 index 76952dc3..00000000 --- a/templates/sysconfig/ad-selfsearch.html +++ /dev/null @@ -1,112 +0,0 @@ -

- {{lang_dnLookup}} -

- -
-
LDAP Self-Query
- - -
-{{lang_onProblemSearchBase}} -

-
-
- - - - - - - - - - {{#ssl}} - - - {{/ssl}} - -
-
-
-
- - - - - - - - - - - - {{#ssl}} - - - {{/ssl}} - - -
-
- diff --git a/templates/sysconfig/ad-start.html b/templates/sysconfig/ad-start.html deleted file mode 100644 index 98546140..00000000 --- a/templates/sysconfig/ad-start.html +++ /dev/null @@ -1,121 +0,0 @@ -

- {{lang_adText1}} -
- {{lang_adText2}} -
- {{lang_adText3}} -

-
dsquery user -name "Username"
-

- {{lang_adText4}} -

- -{{lang_asteriskMandatory}} - -
- - - - -
- {{lang_moduleTitle}} - -
-
- Server * - -
-
- {{lang_bindDN}} * - -
-
- {{lang_password}} * - -
-
- {{lang_searchBase}} - -
-
-
- Home - - - - -
-
- {{lang_homeAttr}} - - - - -
-
-
- -
- {{lang_sslDescription}} -
-
- -
-
-
-
-
- {{lang_customCertificate}} -
------BEGIN CERTIFICATE-----
-MIIFfTCCA...
-.....
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-.....
------END CERTIFICATE-----
- -
-
- -
-
-
-
- - - - diff --git a/templates/sysconfig/ad_ldap-checkconnection.html b/templates/sysconfig/ad_ldap-checkconnection.html deleted file mode 100644 index 5925829a..00000000 --- a/templates/sysconfig/ad_ldap-checkconnection.html +++ /dev/null @@ -1,91 +0,0 @@ -

- {{lang_connectionWait}} -

- -
-
Port Check
-
- - - -
-
-
- - - - - - - - - - {{#ssl}} - - - {{/ssl}} - -
-
-
-
- - - - - - - - - - - {{#ssl}} - - - - {{/ssl}} - - -
-
-
- diff --git a/templates/sysconfig/ad_ldap-checkcredentials.html b/templates/sysconfig/ad_ldap-checkcredentials.html deleted file mode 100644 index 0586209b..00000000 --- a/templates/sysconfig/ad_ldap-checkcredentials.html +++ /dev/null @@ -1,67 +0,0 @@ -

- {{lang_connectionWait}} -

- -
-
LDAP Test-Query
-
-{{lang_onProblemSearchBase}} -

-
-
- - - - - - - - - - {{#ssl}} - - - {{/ssl}} - -
-
-
-
- - - - - - - - - - - {{#ssl}} - - - {{/ssl}} - - - -
-
- diff --git a/templates/sysconfig/ad_ldap-homedir.html b/templates/sysconfig/ad_ldap-homedir.html deleted file mode 100644 index c6250175..00000000 --- a/templates/sysconfig/ad_ldap-homedir.html +++ /dev/null @@ -1,79 +0,0 @@ -
- {{lang_homedirHandling}} -
-
{{lang_handlingNotes}}
- - - -
- - - - - - - - - - {{#ssl}} - - - {{/ssl}} - - -
- -
- -
-
-
- -
- -
-
-
-
{{lang_folderRedirection}}
-
{{lang_redirectionWarning}}
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
- -
-
-
\ No newline at end of file diff --git a/templates/sysconfig/branding-check.html b/templates/sysconfig/branding-check.html deleted file mode 100644 index 8f6ef055..00000000 --- a/templates/sysconfig/branding-check.html +++ /dev/null @@ -1,26 +0,0 @@ -

- {{lang_brandingInfo}} -

-
- {{#svg}} - - {{/svg}} -
-
- {{#png}} - - {{/png}} -
-
-
{{error}}
-
-
- - -
- - -
- -
-
diff --git a/templates/sysconfig/branding-start.html b/templates/sysconfig/branding-start.html deleted file mode 100644 index 09b9ca27..00000000 --- a/templates/sysconfig/branding-start.html +++ /dev/null @@ -1,25 +0,0 @@ -

- {{lang_branding}} -

-
- - -
- - -
- {{lang_or}} -
- -
- - - - {{lang_browseForFile}}… - - -
-
- -
- diff --git a/templates/sysconfig/cfg-finish.html b/templates/sysconfig/cfg-finish.html deleted file mode 100644 index a6e51996..00000000 --- a/templates/sysconfig/cfg-finish.html +++ /dev/null @@ -1,12 +0,0 @@ -

- {{lang_configurationSuccess}} -

- -
- - - -
- -
-
diff --git a/templates/sysconfig/cfg-start.html b/templates/sysconfig/cfg-start.html deleted file mode 100644 index 50f366ea..00000000 --- a/templates/sysconfig/cfg-start.html +++ /dev/null @@ -1,39 +0,0 @@ -
- - -
- {{lang_name}} * - -
-
-

{{lang_configurationChoose}}

- {{#groups}} -
-
{{group}}
-
- {{#modules}} -
- - {{#unique}} - - {{/unique}} - {{^unique}} - - {{/unique}} - - - {{#missing}} - - {{/missing}} -
- {{/modules}} - {{^modules}} -
{{lang_noModuleOfType}}
- {{/modules}} -
-
- {{/groups}} -
- -
-
diff --git a/templates/sysconfig/config-module-list.html b/templates/sysconfig/config-module-list.html deleted file mode 100644 index 6cd77f9e..00000000 --- a/templates/sysconfig/config-module-list.html +++ /dev/null @@ -1,17 +0,0 @@ -
- - - - {{#modules}} - - - - - {{/modules}} -
{{module}} - -
- {{^modules}} -
{{lang_noContent}}
- {{/modules}} -
\ No newline at end of file diff --git a/templates/sysconfig/custom-filelist.html b/templates/sysconfig/custom-filelist.html deleted file mode 100644 index 3ad241dd..00000000 --- a/templates/sysconfig/custom-filelist.html +++ /dev/null @@ -1,16 +0,0 @@ - - - -{{#files}} - - {{#isdir}} - - {{/isdir}} - {{^isdir}} - - - {{/isdir}} - - {{/files}} -
{{name}}{{name}}{{size}}
-{{lang_back}} « diff --git a/templates/sysconfig/custom-fileselect.html b/templates/sysconfig/custom-fileselect.html deleted file mode 100644 index 000c8d10..00000000 --- a/templates/sysconfig/custom-fileselect.html +++ /dev/null @@ -1,31 +0,0 @@ -
- - - -
- {{lang_moduleName}} - -
-
- -
-
-
-

{{lang_checkFileContent}}

- - {{#files}} - - {{#isdir}} - - {{/isdir}} - {{^isdir}} - - - {{/isdir}} - - {{/files}} -
{{name}}{{name}}{{size}}
-
- -
-
diff --git a/templates/sysconfig/custom-upload.html b/templates/sysconfig/custom-upload.html deleted file mode 100644 index c453a97d..00000000 --- a/templates/sysconfig/custom-upload.html +++ /dev/null @@ -1,18 +0,0 @@ -

{{lang_customModuleInfo1}}

- -

{{lang_customModuleInfo2}}

- -
- - -
- - - - {{lang_browseForFile}}… - - -
-

{{lang_supportedFiles}}: .tar.gz, .tar.bz2, .zip

- -
diff --git a/templates/sysconfig/ldap-finish.html b/templates/sysconfig/ldap-finish.html deleted file mode 100644 index a735e792..00000000 --- a/templates/sysconfig/ldap-finish.html +++ /dev/null @@ -1,29 +0,0 @@ -

- {{lang_ldapStarted}} -

- -
-
{{lang_generateModule}}
-
-
- - - diff --git a/templates/sysconfig/ldap-start.html b/templates/sysconfig/ldap-start.html deleted file mode 100644 index 7892b63f..00000000 --- a/templates/sysconfig/ldap-start.html +++ /dev/null @@ -1,101 +0,0 @@ -

- {{lang_ldapText1}} -
- {{lang_ldapText2}} -

- -
- - - - -
- {{lang_moduleTitle}} - -
-
- Server * - - -
-
- {{lang_bindDN}} - - -
-
- {{lang_password}} - - -
-
- {{lang_searchBase}} * - - -
-
-
- Home - - - - -
-
-
- -
- {{lang_sslDescription}} -
-
- -
-
-
-
-
- {{lang_customCertificate}} -
------BEGIN CERTIFICATE-----
-MIIFfTCCA...
-.....
------END CERTIFICATE-----
------BEGIN CERTIFICATE-----
-.....
------END CERTIFICATE-----
- -
-
- -
-
-
-
- - diff --git a/templates/sysconfig/sshconfig-start.html b/templates/sysconfig/sshconfig-start.html deleted file mode 100644 index 2aa409d3..00000000 --- a/templates/sysconfig/sshconfig-start.html +++ /dev/null @@ -1,27 +0,0 @@ -
- - -
- {{lang_moduleName}} - -
-
- -

{{lang_allowPassInfo}}

-
-
- - - {{lang_rootKeyInfo}} -
-
- - - {{lang_listenPortInfo}} -
- -
- diff --git a/templates/sysconfig/start.html b/templates/sysconfig/start.html deleted file mode 100644 index f55a5501..00000000 --- a/templates/sysconfig/start.html +++ /dev/null @@ -1,12 +0,0 @@ -

{{lang_moduleChoose}}

- -{{#modules}} -
-
- {{title}} {{lang_add}} -
-
- {{description}} -
-
-{{/modules}} diff --git a/templates/systemstatus/_page.html b/templates/systemstatus/_page.html deleted file mode 100644 index 51aa5b55..00000000 --- a/templates/systemstatus/_page.html +++ /dev/null @@ -1,129 +0,0 @@ -{{#rebootTask}} -
Reboot...
-{{/rebootTask}} - -
- -
-
-
- {{lang_space}} -
-
- -
-
-
- -
-
-
- {{lang_services}} -
-
- -
-
-
- -
- - -
- -
-
-
- {{lang_addressConfiguration}} -
-
- -
-
-
- -
-
-
- {{lang_system}} -
-
- -
-
-
- -
- -
- -
-
-
- {{lang_maintenance}} -
-
-
- - -
Server Reboot
- - -
-
-
-
-
- -
- -

{{lang_advanced}}

- -
-
- {{lang_dmsdLog}} -
-
- -
-
-
-
- {{lang_ldadpLog}} -
-
- -
-
-
-
- netstat -tulpn -
-
- -
-
-
-
- ps auxf -
-
- -
-
- - diff --git a/templates/systemstatus/addresses.html b/templates/systemstatus/addresses.html deleted file mode 100644 index ce92c4d5..00000000 --- a/templates/systemstatus/addresses.html +++ /dev/null @@ -1,8 +0,0 @@ - - {{#addresses}} - - - - - {{/addresses}} -
{{ip}}({{iface}})
\ No newline at end of file diff --git a/templates/systemstatus/diskstat.html b/templates/systemstatus/diskstat.html deleted file mode 100644 index 528d9792..00000000 --- a/templates/systemstatus/diskstat.html +++ /dev/null @@ -1,63 +0,0 @@ -
- {{#system}} - {{lang_systemPartition}} -
-
{{lang_capacity}}: {{size}}
-
{{lang_free}}: {{free}}
- {{/system}} - {{^system}} - {{lang_systemStoreError}} - {{/system}} -
-
- {{#store}} - {{lang_vmStore}} -
-
{{lang_capacity}}: {{size}}
-
{{lang_free}}: {{free}}
- {{/store}} - {{^store}} - {{lang_vmStoreError}} - {{/store}} -
-
-{{#notConfigured}} -
{{lang_storeNotConfigured}}
-{{/notConfigured}} -{{#storeMissing}} -
{{lang_storeMissingExpected}} {{storeMissing}}
-{{/storeMissing}} -{{#wrongStore}} -
{{lang_foundStore}} {{wrongStore}}
-{{/wrongStore}} -{{lang_goToStoreConf}} - diff --git a/templates/systemstatus/services.html b/templates/systemstatus/services.html deleted file mode 100644 index 6c4f0b93..00000000 --- a/templates/systemstatus/services.html +++ /dev/null @@ -1,6 +0,0 @@ -{{#ldadpError}} -
{{ldadpError}}
-{{/ldadpError}} -{{^ldadpError}} -
LDAP-AD-Proxy: OK
-{{/ldadpError}} diff --git a/templates/systemstatus/systeminfo.html b/templates/systemstatus/systeminfo.html deleted file mode 100644 index ed4a1532..00000000 --- a/templates/systemstatus/systeminfo.html +++ /dev/null @@ -1,115 +0,0 @@ -
- {{lang_uptimeOS}}: {{uptime}} -
- -
- {{lang_cpuLoad}} - {{#cpuLoadOk}} -
-
{{lang_average}}: {{cpuLoad}}%
-
{{lang_onlyOS}}: {{cpuSystem}}%
-
{{lang_logicCPUs}}: {{cpuCount}}
- {{/cpuLoadOk}} - {{^cpuLoadOk}} - {{lang_notDetermined}} - {{/cpuLoadOk}} -
- -
- {{lang_ramUsage}} - {{#memTotal}} -
-
{{lang_total}}: {{memTotal}}
-
{{lang_free}}: {{memFree}}
- {{/memTotal}} - {{^memTotal}} - {{lang_notDetermined}} - {{/memTotal}} -
- -
- {{lang_swapUsage}} - {{#memTotal}} -
-
{{lang_total}}: {{swapTotal}}
-
{{lang_occupied}}: {{swapUsed}}
- {{/memTotal}} - {{^memTotal}} - {{lang_notDetermined}} - {{/memTotal}} -
- -
- -{{#swapWarning}} -
- {{lang_attention}} {{lang_swapWarning}} -
-{{/swapWarning}} - - diff --git a/templates/tm-callback-trigger.html b/templates/tm-callback-trigger.html deleted file mode 100644 index cd03a1fe..00000000 --- a/templates/tm-callback-trigger.html +++ /dev/null @@ -1,15 +0,0 @@ - \ No newline at end of file diff --git a/templates/translation/_page.html b/templates/translation/_page.html deleted file mode 100644 index 37122d7e..00000000 --- a/templates/translation/_page.html +++ /dev/null @@ -1,15 +0,0 @@ -
-
- {{lang_langAdministration}} -
- -
diff --git a/templates/translation/edit.html b/templates/translation/edit.html deleted file mode 100644 index dc01deb6..00000000 --- a/templates/translation/edit.html +++ /dev/null @@ -1,71 +0,0 @@ -
-
-
- {{path}} -
-
-

{{lang_templateAdminHelp}}

-
- {{lang_templateHint}} -
-
- - - {{lang_back}} - - - - - - - {{#langs}} - - {{/langs}} - - - - - {{#tags}} - - - {{#langs}} - - {{/langs}} - - - {{/tags}} - - - -
Mustache Tag{{name}}
{{tag}} - {{^big}} - - {{/big}} - {{#big}} - - {{/big}} - - -
- {{lang_back}} - - -
-
-
-
- diff --git a/templates/translation/template-list.html b/templates/translation/template-list.html deleted file mode 100644 index 881fc5af..00000000 --- a/templates/translation/template-list.html +++ /dev/null @@ -1,32 +0,0 @@ -
-
- {{lang_langAdministration}} -
-
-

{{lang_adminInfo}}

-
-
-
- - - - - - - - - {{#table}} - - - - - {{/table}} - -
Template{{lang_status}}
{{template}}{{{status}}}
-
- - diff --git a/templates/vmstore/mount.html b/templates/vmstore/mount.html deleted file mode 100644 index eabee81a..00000000 --- a/templates/vmstore/mount.html +++ /dev/null @@ -1,25 +0,0 @@ -
-
- {{lang_vmLocationConfiguration}} -
- -
-
{{lang_configure}}
- -
- - - -
-
\ No newline at end of file diff --git a/templates/webinterface/httpd-restart.html b/templates/webinterface/httpd-restart.html deleted file mode 100644 index cc84aafb..00000000 --- a/templates/webinterface/httpd-restart.html +++ /dev/null @@ -1,6 +0,0 @@ -
-
{{lang_applyingSettings}}
-
-
{{lang_installAndRestart}}
-
-
diff --git a/templates/webinterface/https.html b/templates/webinterface/https.html deleted file mode 100644 index c6161cd6..00000000 --- a/templates/webinterface/https.html +++ /dev/null @@ -1,60 +0,0 @@ -
- - -
-
{{lang_httpsSettings}}
-
-

{{lang_description}}

- {{^httpsEnabled}} -

{{lang_HttpsIsDisabled}}

- {{/httpsEnabled}} - {{#httpsEnabled}} -
- - - {{lang_noHttps}} - -
- {{/httpsEnabled}} -
- - - {{lang_randomCert}} - -
-
- - - {{lang_customCert}} - -
- -
- -
-
-
-
diff --git a/templates/webinterface/passwords.html b/templates/webinterface/passwords.html deleted file mode 100644 index f9fda016..00000000 --- a/templates/webinterface/passwords.html +++ /dev/null @@ -1,25 +0,0 @@ -
- - -
-
{{lang_passwordFields}}
-
-

{{lang_description}}

-
- - - {{lang_showPasswords}} - -
-
- - - {{lang_hidePasswords}} - -
-
- -
-
-
-
-- cgit v1.2.3-55-g7522