#12 App widgets
This commit is contained in:
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
replay_pid*
|
||||||
|
|
||||||
|
*/target/*
|
||||||
|
.idea/*
|
||||||
@@ -8,6 +8,7 @@ import org.springframework.ui.Model;
|
|||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class DashboardController {
|
public class DashboardController {
|
||||||
@@ -20,6 +21,7 @@ public class DashboardController {
|
|||||||
@GetMapping("/dashboard")
|
@GetMapping("/dashboard")
|
||||||
public String start(Model model, HttpServletRequest httpServletRequest, String sortOrder) {
|
public String start(Model model, HttpServletRequest httpServletRequest, String sortOrder) {
|
||||||
model.addAttribute("apps", this.appRegistry.getAll());
|
model.addAttribute("apps", this.appRegistry.getAll());
|
||||||
|
model.addAttribute("widgets", this.appRegistry.getAll().stream().flatMap(a -> a.getWidgets().stream()).collect(Collectors.toList()));
|
||||||
this.webContainerSharedConfig.addDefaults(model);
|
this.webContainerSharedConfig.addDefaults(model);
|
||||||
|
|
||||||
return "dashboard/index";
|
return "dashboard/index";
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
nbscloud.dashboard.greeting=Welcome to nbscloud
|
||||||
|
|
||||||
|
nbscloud.dashboard.index.title=nbscloud\: dashboard
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
nbscloud.dashboard.greeting=Willkommen bei nbscloud
|
||||||
|
|
||||||
|
nbscloud.dashboard.index.title=nbscloud\: \u00DCbersicht
|
||||||
@@ -1,3 +1,35 @@
|
|||||||
#content-container {
|
#content-container {
|
||||||
padding-top: 2em;
|
padding-top: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#widgets-container {
|
||||||
|
padding: 2em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
align-content: space-between;
|
||||||
|
row-gap: 2em;
|
||||||
|
column-gap: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget {
|
||||||
|
flex-grow: 1;
|
||||||
|
background-color: #1d2121;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.widget-heading {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.greeting {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin-top: 0.83em;
|
||||||
|
margin-bottom: 0.83em;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
@@ -14,7 +14,14 @@
|
|||||||
<div id="main-container">
|
<div id="main-container">
|
||||||
<div th:replace="includes/header :: header"/>
|
<div th:replace="includes/header :: header"/>
|
||||||
<div id="content-container">
|
<div id="content-container">
|
||||||
Welcome to nbscloud
|
<div id="greetings-container">
|
||||||
|
<p class="greeting" th:text="#{nbscloud.dashboard.greeting}" />
|
||||||
|
</div>
|
||||||
|
<div id="widgets-container">
|
||||||
|
<th:block th:each="widget : ${widgets}">
|
||||||
|
<th:block th:utext="${#servletContext.getRequestDispatcher('/' + widget.path).include(#request,#response)}"/>
|
||||||
|
</th:block>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div th:replace="includes/footer :: footer"/>
|
<div th:replace="includes/footer :: footer"/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StreamUtils;
|
import org.springframework.util.StreamUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -160,7 +158,7 @@ public class FileSystemService {
|
|||||||
Files.walkFileTree(targetPath, new SimpleFileVisitor<Path>() {
|
Files.walkFileTree(targetPath, new SimpleFileVisitor<Path>() {
|
||||||
@Override
|
@Override
|
||||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
if(Files.isDirectory(file)) {
|
if (Files.isDirectory(file)) {
|
||||||
return FileVisitResult.CONTINUE;
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +205,7 @@ public class FileSystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getSize(Path name) {
|
public long getSize(Path name) {
|
||||||
try {
|
try {
|
||||||
return Files.size(name);
|
return Files.size(name);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -215,6 +213,34 @@ public class FileSystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDevice() {
|
||||||
|
try {
|
||||||
|
final Process process = Runtime.getRuntime()
|
||||||
|
.exec(new String[]{"findmnt", "-n", "-o", "SOURCE", "--target", this.locationTracker.getBaseDirPath().toString()});
|
||||||
|
final String device = new BufferedReader(new InputStreamReader(process.getInputStream())).readLine();
|
||||||
|
|
||||||
|
process.destroy();
|
||||||
|
|
||||||
|
return device;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new FileSystemServiceException("Could not get file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSpaceOnDevice(String device) {
|
||||||
|
try {
|
||||||
|
final Process process = Runtime.getRuntime()
|
||||||
|
.exec(new String[]{"lsblk", "-b", "-o", "SIZE", "-n", device});
|
||||||
|
final String space = new BufferedReader(new InputStreamReader(process.getInputStream())).readLine();
|
||||||
|
|
||||||
|
process.destroy();
|
||||||
|
|
||||||
|
return Long.parseLong(space);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new FileSystemServiceException("Could not get file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getMimeType(String name) {
|
public String getMimeType(String name) {
|
||||||
try {
|
try {
|
||||||
final String detectedMimeType = this.mimeTypeDetector.detectMimeType(this.locationTracker.resolve(name));
|
final String detectedMimeType = this.mimeTypeDetector.detectMimeType(this.locationTracker.resolve(name));
|
||||||
|
|||||||
@@ -1,19 +1,27 @@
|
|||||||
package de.nbscloud.files;
|
package de.nbscloud.files;
|
||||||
|
|
||||||
|
import de.nbscloud.files.widget.DiskUsageWidget;
|
||||||
import de.nbscloud.webcontainer.registry.App;
|
import de.nbscloud.webcontainer.registry.App;
|
||||||
import de.nbscloud.webcontainer.registry.AppRegistry;
|
import de.nbscloud.webcontainer.registry.AppRegistry;
|
||||||
|
import de.nbscloud.webcontainer.registry.Widget;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class FilesApp implements App, InitializingBean {
|
public class FilesApp implements App, InitializingBean {
|
||||||
|
public static final String ID = "files";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AppRegistry appRegistry;
|
private AppRegistry appRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "files";
|
return ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,6 +39,11 @@ public class FilesApp implements App, InitializingBean {
|
|||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Widget> getWidgets() {
|
||||||
|
return List.of(new DiskUsageWidget());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
this.appRegistry.registerApp(this);
|
this.appRegistry.registerApp(this);
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package de.nbscloud.files.controller;
|
||||||
|
|
||||||
|
import de.nbscloud.files.FileSystemService;
|
||||||
|
import de.nbscloud.files.LocationTracker;
|
||||||
|
import de.nbscloud.files.config.FilesConfig;
|
||||||
|
import de.nbscloud.webcontainer.shared.config.WebContainerSharedConfig;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class WidgetController {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(WidgetController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FilesConfig filesConfig;
|
||||||
|
@Autowired
|
||||||
|
private LocationTracker locationTracker;
|
||||||
|
@Autowired
|
||||||
|
private WebContainerSharedConfig webContainerSharedConfig;
|
||||||
|
@Autowired
|
||||||
|
private FileSystemService fileSystemService;
|
||||||
|
|
||||||
|
@GetMapping("files/widgets/diskUsage")
|
||||||
|
public String getDiskUsage(HttpServletRequest request, HttpServletResponse response, Model model) {
|
||||||
|
final String device = this.fileSystemService.getDevice();
|
||||||
|
|
||||||
|
model.addAttribute("baseDir", this.filesConfig.getBaseDir());
|
||||||
|
model.addAttribute("device", device);
|
||||||
|
model.addAttribute("available", this.fileSystemService.getSpaceOnDevice(device));
|
||||||
|
model.addAttribute("used", FileUtils.sizeOfDirectory(Paths.get(this.filesConfig.getBaseDir()).toFile()));
|
||||||
|
|
||||||
|
return "files/widgets/diskUsage :: file-disk-usage";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package de.nbscloud.files.widget;
|
||||||
|
|
||||||
|
import de.nbscloud.files.FilesApp;
|
||||||
|
import de.nbscloud.webcontainer.registry.Widget;
|
||||||
|
|
||||||
|
public class DiskUsageWidget implements Widget {
|
||||||
|
@Override
|
||||||
|
public String getPath() {
|
||||||
|
return FilesApp.ID + "/widgets/diskUsage";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,12 @@ nbscloud.files.share.submit=Share
|
|||||||
|
|
||||||
nbscloud.files.share-message=Shared file\:\u0020
|
nbscloud.files.share-message=Shared file\:\u0020
|
||||||
|
|
||||||
|
nbscloud.files.file-disk-usage-widget.heading=files disk usage
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.basedir=Base dir\:
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.device=Host device\:
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.available=Available\:
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.used=Used\:
|
||||||
|
|
||||||
nbscloud.files.delete.success=File deleted
|
nbscloud.files.delete.success=File deleted
|
||||||
nbscloud.files.rename.success=File renamed
|
nbscloud.files.rename.success=File renamed
|
||||||
nbscloud.files.created.file.success=File created
|
nbscloud.files.created.file.success=File created
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ nbscloud.files.share.submit=Teilen
|
|||||||
|
|
||||||
nbscloud.files.share-message=Datei geteilt\:\u0020
|
nbscloud.files.share-message=Datei geteilt\:\u0020
|
||||||
|
|
||||||
|
nbscloud.files.file-disk-usage-widget.heading=Dateien Festplattennutzung
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.basedir=Verzeichnis\:
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.device=Ger\u00E4t\:
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.available=Verf\u00FCgbar\:
|
||||||
|
nbscloud.files.file-disk-usage-widget-table.used=Belegt\:
|
||||||
|
|
||||||
nbscloud.files.delete.success=Datei gel\u00F6scht
|
nbscloud.files.delete.success=Datei gel\u00F6scht
|
||||||
nbscloud.files.rename.success=Datei verschoben/umbenannt
|
nbscloud.files.rename.success=Datei verschoben/umbenannt
|
||||||
nbscloud.files.created.file.success=Datei erstellt
|
nbscloud.files.created.file.success=Datei erstellt
|
||||||
|
|||||||
@@ -175,3 +175,7 @@
|
|||||||
#gallery-link {
|
#gallery-link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#file-disk-usage-widget {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<div id="file-disk-usage-widget" class="widget" th:fragment="file-disk-usage">
|
||||||
|
<p class="widget-heading" th:text="#{nbscloud.files.file-disk-usage-widget.heading}"/>
|
||||||
|
<table id="file-disk-usage-widget-table">
|
||||||
|
<tr>
|
||||||
|
<td th:text="#{nbscloud.files.file-disk-usage-widget-table.basedir}" />
|
||||||
|
<td th:text="${baseDir}" />
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td th:text="#{nbscloud.files.file-disk-usage-widget-table.device}" />
|
||||||
|
<td th:text="${device}" />
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td th:text="#{nbscloud.files.file-disk-usage-widget-table.available}" />
|
||||||
|
<td th:text="${@filesFormatter.formatSize(available)}" />
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td th:text="#{nbscloud.files.file-disk-usage-widget-table.used}" />
|
||||||
|
<td th:text="${@filesFormatter.formatSize(used)}" />
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package de.nbscloud.webcontainer.registry;
|
package de.nbscloud.webcontainer.registry;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public interface App {
|
public interface App {
|
||||||
// New app:
|
// New app:
|
||||||
// 1) Create module
|
// 1) Create module
|
||||||
@@ -15,4 +18,8 @@ public interface App {
|
|||||||
String getStartPath();
|
String getStartPath();
|
||||||
|
|
||||||
int getIndex();
|
int getIndex();
|
||||||
|
|
||||||
|
default Collection<Widget> getWidgets() {
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package de.nbscloud.webcontainer.registry;
|
||||||
|
|
||||||
|
public interface Widget {
|
||||||
|
String getPath();
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ info.build.group=@project.groupId@
|
|||||||
info.build.artifact=@project.artifactId@
|
info.build.artifact=@project.artifactId@
|
||||||
info.build.version=@project.version@
|
info.build.version=@project.version@
|
||||||
|
|
||||||
spring.messages.basename=i18n/container_messages,i18n/files_messages
|
spring.messages.basename=i18n/container_messages,i18n/files_messages,i18n/dashboard_messages
|
||||||
|
|
||||||
spring.servlet.multipart.max-file-size=-1
|
spring.servlet.multipart.max-file-size=-1
|
||||||
spring.servlet.multipart.max-request-size=-1
|
spring.servlet.multipart.max-request-size=-1
|
||||||
|
|||||||
Reference in New Issue
Block a user