diff --git a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/Extension.java b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ExtensionInfo.java similarity index 97% rename from cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/Extension.java rename to cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ExtensionInfo.java index 16f02e6d..08c5b26c 100644 --- a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/Extension.java +++ b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ExtensionInfo.java @@ -29,7 +29,7 @@ * @author t.marx */ @Data -public class Extension { +public class ExtensionInfo { private String id; private String version; diff --git a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ModuleInfo.java b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ModuleInfo.java new file mode 100644 index 00000000..de46181e --- /dev/null +++ b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ModuleInfo.java @@ -0,0 +1,42 @@ +package com.github.thmarx.cms.extensions.repository; + +/*- + * #%L + * cms-extensions + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import lombok.Data; + +/** + * + * @author t.marx + */ +@Data +public class ModuleInfo { + + private String id; + private String version; + private String name; + private String description; + private String author; + private String url; + private String compatibility; + private String file; +} diff --git a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ModulePacker.java b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ModulePacker.java new file mode 100644 index 00000000..cd2f53bb --- /dev/null +++ b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ModulePacker.java @@ -0,0 +1,121 @@ +package com.github.thmarx.cms.extensions.repository; + +/*- + * #%L + * modules-manager + * %% + * Copyright (C) 2023 Thorsten Marx + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * + * @author marx + */ +public class ModulePacker { + + /** + * Delets a dir recursively deleting anything inside it. + * + * @param dir The dir to delete + * @return true if the dir was successfully deleted + */ + protected static boolean deleteDirectory(File dir) { + if (!dir.exists() || !dir.isDirectory()) { + return false; + } + + String[] files = dir.list(); + for (int i = 0, len = files.length; i < len; i++) { + File f = new File(dir, files[i]); + if (f.isDirectory()) { + deleteDirectory(f); + } else { + f.delete(); + } + } + return dir.delete(); + } + + protected static boolean moveDirectoy (final File src, final File dest) { + return src.renameTo(dest); + } + + /** + * Unpack a zip file + * + * @param theFile + * @param targetDir + * @return the file + * @throws IOException + */ + protected static File unpackArchive(File theFile, File targetDir) throws IOException { + if (!theFile.exists()) { + throw new IOException(theFile.getAbsolutePath() + " does not exist"); + } + if (!buildDirectory(targetDir)) { + throw new IOException("Could not create directory: " + targetDir); + } + boolean found = false; + String moduleid = null; + try (ZipFile zipFile = new ZipFile(theFile)) { + for (Enumeration entries = zipFile.entries(); entries.hasMoreElements();) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + File file = new File(targetDir, File.separator + entry.getName()); + if (entry.isDirectory() && !found) { + moduleid = file.getName(); + found = true; + } + if (!buildDirectory(file.getParentFile())) { + throw new IOException("Could not create directory: " + file.getParentFile()); + } + if (!entry.isDirectory()) { + copyInputStream(zipFile.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(file))); + } else if (!buildDirectory(file)) { + throw new IOException("Could not create directory: " + file); + } + } + } + return new File(targetDir, moduleid); + } + + private static void copyInputStream(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[1024]; + int len = in.read(buffer); + while (len >= 0) { + out.write(buffer, 0, len); + len = in.read(buffer); + } + in.close(); + out.close(); + } + + private static boolean buildDirectory(File file) { + return file.exists() || file.mkdirs(); + } +} diff --git a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/RemoteModuleRepository.java b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/RemoteModuleRepository.java new file mode 100644 index 00000000..d9fba40a --- /dev/null +++ b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/RemoteModuleRepository.java @@ -0,0 +1,114 @@ +package com.github.thmarx.cms.extensions.repository; + +/*- + * #%L + * cms-extensions + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.yaml.snakeyaml.Yaml; + +/** + * + * @author t.marx + * @param + */ +@Slf4j +@RequiredArgsConstructor +public class RemoteModuleRepository { + + static HttpClient client = HttpClient.newBuilder() + .version(HttpClient.Version.HTTP_2) + .followRedirects(HttpClient.Redirect.ALWAYS) + .build(); + + private final Class type; + private final String baseUrl; + + public boolean exists(String id) { + try { + var moduleInfoUrl = baseUrl + "/main/%s/%s.yaml" + .formatted(id, id); + + URI uri = URI.create(moduleInfoUrl); + HttpRequest request = HttpRequest.newBuilder(uri).build(); + return client.send(request, HttpResponse.BodyHandlers.ofString()).statusCode() == 200; + } catch (IOException | InterruptedException ex) { + log.error("", ex); + } + + return false; + } + + public Optional getInfo(String extension) { + try { + var moduleInfoUrl = baseUrl + "/main/%s/%s.yaml" + .formatted(extension, extension); + + URI uri = URI.create(moduleInfoUrl); + HttpRequest request = HttpRequest.newBuilder(uri) + .build(); + final HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200) { + return Optional.empty(); + } + String content = response.body(); + + return Optional.of(new Yaml().loadAs(content, type)); + } catch (IOException | InterruptedException ex) { + log.error("", ex); + } + + return Optional.empty(); + } + + public void download(String url, Path target) { + + try { + Path tempDirectory = Files.createTempDirectory("modules"); + + var request = HttpRequest.newBuilder(URI.create(url)).GET().build(); + HttpResponse response = client.send( + request, + HttpResponse.BodyHandlers.ofFile(tempDirectory.resolve(System.currentTimeMillis() + ".zip"))); + + var downloaded = response.body(); + + File moduleTempDir = ModulePacker.unpackArchive(downloaded.toFile(), tempDirectory.toFile()); + + ModulePacker.moveDirectoy(moduleTempDir, target.resolve(moduleTempDir.getName()).toFile()); + } catch (Exception ex) { + log.error("", ex); + throw new RuntimeException("error downloading module"); + } + } +} diff --git a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/RemoteRepository.java b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/RemoteRepository.java index 10cec1cb..dc5f6a2a 100644 --- a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/RemoteRepository.java +++ b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/RemoteRepository.java @@ -27,12 +27,9 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse.BodyHandlers; -import java.util.Collections; -import java.util.Map; import java.util.Optional; import lombok.extern.slf4j.Slf4j; import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; /** * @@ -73,7 +70,7 @@ public Optional getContent (String extension) { return Optional.empty(); } - public Optional getInfo (String extension) { + public Optional getInfo (String extension) { try { var moduleInfoUrl = "https://raw.githubusercontent.com/thmarx/extension-registry/main/%s/%s.yaml" .formatted(extension, extension); @@ -83,7 +80,7 @@ public Optional getInfo (String extension) { String content = client.send(request, BodyHandlers.ofString()).body(); - return Optional.of(new Yaml().loadAs(content, Extension.class)); + return Optional.of(new Yaml().loadAs(content, ExtensionInfo.class)); } catch (IOException | InterruptedException ex) { log.error("", ex); } diff --git a/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ThemeInfo.java b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ThemeInfo.java new file mode 100644 index 00000000..dc57aba1 --- /dev/null +++ b/cms-extensions/src/main/java/com/github/thmarx/cms/extensions/repository/ThemeInfo.java @@ -0,0 +1,42 @@ +package com.github.thmarx.cms.extensions.repository; + +/*- + * #%L + * cms-extensions + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import lombok.Data; + +/** + * + * @author t.marx + */ +@Data +public class ThemeInfo { + + private String id; + private String version; + private String name; + private String description; + private String author; + private String url; + private String compatibility; + private String file; +} diff --git a/cms-extensions/src/test/java/com/github/thmarx/cms/extensions/repository/RemoteModuleRepositoryTest.java b/cms-extensions/src/test/java/com/github/thmarx/cms/extensions/repository/RemoteModuleRepositoryTest.java new file mode 100644 index 00000000..5557a640 --- /dev/null +++ b/cms-extensions/src/test/java/com/github/thmarx/cms/extensions/repository/RemoteModuleRepositoryTest.java @@ -0,0 +1,70 @@ +package com.github.thmarx.cms.extensions.repository; + +/*- + * #%L + * cms-extensions + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * + * @author t.marx + */ +public class RemoteModuleRepositoryTest { + + + RemoteModuleRepository moduleRepository = new RemoteModuleRepository<>( + ModuleInfo.class, + "https://raw.githubusercontent.com/thmarx/module-registry" + ); + + @Test + public void test_exist() { + Assertions.assertThat(moduleRepository.exists("none-module")).isFalse(); + + Assertions.assertThat(moduleRepository.exists("downloads-module")).isTrue(); + } + + @Test + public void test_info() { + Assertions.assertThat(moduleRepository.getInfo("none-module")).isEmpty(); + + Assertions.assertThat(moduleRepository.getInfo("downloads-module")) + .isPresent() + .get() + .isInstanceOf(ModuleInfo.class) + ; + } + + @Test + public void test_download() throws IOException { + var moduleInfo = moduleRepository.getInfo("downloads-module").get(); + + var modulesPath = Path.of("target/modules-" + System.currentTimeMillis()); + Files.createDirectories(modulesPath); + + moduleRepository.download(moduleInfo.getFile(), modulesPath); + } +} diff --git a/cms-server/hosts/demo/site.yaml b/cms-server/hosts/demo/site.yaml index f93a8c9f..2c83ecb0 100644 --- a/cms-server/hosts/demo/site.yaml +++ b/cms-server/hosts/demo/site.yaml @@ -4,9 +4,6 @@ hostname: baseurl: "http://localhost:1010" language: en theme: demo -modules: - active: - - seo-module media: formats: - name: small diff --git a/cms-server/src/main/java/com/github/thmarx/cms/CMSServer.java b/cms-server/src/main/java/com/github/thmarx/cms/CMSServer.java index 4184a573..a17b8d80 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/CMSServer.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/CMSServer.java @@ -22,16 +22,35 @@ * #L% */ +import com.github.thmarx.cms.api.Constants; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Properties; +import lombok.extern.slf4j.Slf4j; import org.semver4j.Semver; /** * * @author t.marx */ +@Slf4j public class CMSServer { + public static boolean isRunning () { + if (!Files.exists(Path.of(Constants.PID_FILE))) { + return false; + } + try { + var pid = Files.readString(Path.of(Constants.PID_FILE)); + + return ProcessHandle.of(Long.parseLong(pid)).isPresent(); + } catch (IOException ex) { + log.error("", ex); + } + return false; + } + public static Semver getVersion () { try (var in = Startup.class.getResourceAsStream("application.properties")) { Properties props = new Properties(); diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/ServerCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/ServerCommand.java index 23b59914..ca3a832b 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/cli/ServerCommand.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/ServerCommand.java @@ -26,6 +26,8 @@ import com.github.thmarx.cms.cli.commands.RemoveUser; import com.github.thmarx.cms.cli.commands.Startup; import com.github.thmarx.cms.cli.commands.Stop; +import com.github.thmarx.cms.cli.commands.Module; +import com.github.thmarx.cms.cli.commands.Theme; import lombok.extern.slf4j.Slf4j; import picocli.CommandLine; @@ -34,7 +36,7 @@ * @author t.marx */ @CommandLine.Command(name = "server", subcommands = { - Startup.class, AddUser.class, RemoveUser.class, Stop.class, Extension.class}) + Startup.class, AddUser.class, RemoveUser.class, Stop.class, Extension.class, Module.class, Theme.class}) @Slf4j public class ServerCommand implements Runnable { diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/Module.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/Module.java new file mode 100644 index 00000000..3119f3b4 --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/Module.java @@ -0,0 +1,46 @@ +package com.github.thmarx.cms.cli.commands; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +import com.github.thmarx.cms.cli.commands.themes.InfoCommand; +import com.github.thmarx.cms.cli.commands.themes.GetCommand; +import lombok.extern.slf4j.Slf4j; +import picocli.CommandLine; + +/** + * + * @author t.marx + */ +@CommandLine.Command( + name = "module", + subcommands = { + InfoCommand.class, + GetCommand.class + }) +@Slf4j +public class Module implements Runnable { + + @Override + public void run() { + System.out.println("Subcommand needed: 'install' or 'info'"); + } +} diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/Theme.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/Theme.java new file mode 100644 index 00000000..21e60fbd --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/Theme.java @@ -0,0 +1,46 @@ +package com.github.thmarx.cms.cli.commands; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +import com.github.thmarx.cms.cli.commands.themes.InfoCommand; +import com.github.thmarx.cms.cli.commands.themes.GetCommand; +import lombok.extern.slf4j.Slf4j; +import picocli.CommandLine; + +/** + * + * @author t.marx + */ +@CommandLine.Command( + name = "theme", + subcommands = { + InfoCommand.class, + GetCommand.class + }) +@Slf4j +public class Theme implements Runnable { + + @Override + public void run() { + System.out.println("Subcommand needed: 'install' or 'info'"); + } +} diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/extensions/InstallCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/extensions/InstallCommand.java index cfa5230a..5cdcfabe 100644 --- a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/extensions/InstallCommand.java +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/extensions/InstallCommand.java @@ -61,12 +61,12 @@ public void run() { if (repository.exists(extension)) { if (!isCompatibleWithServer(extension)) { - throw new RuntimeException("module is not compatible with server version"); + throw new RuntimeException("the extension is not compatible with server version"); } Optional content = repository.getContent(extension); if (content.isEmpty()) { - throw new RuntimeException("module content not found"); + throw new RuntimeException("the extension content not found"); } try { diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/AbstractModuleCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/AbstractModuleCommand.java new file mode 100644 index 00000000..ed51d86c --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/AbstractModuleCommand.java @@ -0,0 +1,49 @@ +package com.github.thmarx.cms.cli.commands.modules; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.github.thmarx.cms.CMSServer; +import com.github.thmarx.cms.extensions.repository.ModuleInfo; +import com.github.thmarx.cms.extensions.repository.RemoteModuleRepository; +import lombok.Getter; + +/** + * + * @author t.marx + */ +public abstract class AbstractModuleCommand { + + public static final String DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/thmarx/module-registry"; + + @Getter + private RemoteModuleRepository repository = new RemoteModuleRepository(ModuleInfo.class, DEFAULT_REGISTRY_URL); + + public boolean isCompatibleWithServer(String extension) { + var info = repository.getInfo(extension); + if (info.isEmpty()) { + throw new RuntimeException("module not found"); + } + + return CMSServer.getVersion().satisfies(info.get().getCompatibility()); + } +} diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/GetCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/GetCommand.java new file mode 100644 index 00000000..d7ffbad4 --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/GetCommand.java @@ -0,0 +1,68 @@ +package com.github.thmarx.cms.cli.commands.modules; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.github.thmarx.cms.cli.commands.themes.AbstractThemeCommand; +import com.github.thmarx.cms.CMSServer; +import java.nio.file.Path; +import lombok.extern.slf4j.Slf4j; +import picocli.CommandLine; + +/** + * + * @author t.marx + */ +@Slf4j +@CommandLine.Command(name = "get") +public class GetCommand extends AbstractThemeCommand implements Runnable { + + @CommandLine.Parameters( + paramLabel = "", + index = "0", + description = "The id of the module." + ) + private String module = ""; + + @Override + public void run() { + + if (CMSServer.isRunning()) { + System.out.println("modules can not be modified in running system"); + System.exit(0); + } + + if (getRepository().exists(module)) { + + if (!isCompatibleWithServer(module)) { + throw new RuntimeException("module is not compatible with server version"); + } + + var info = getRepository().getInfo(module).get(); + + System.out.println("get module"); + System.out.println("from: " + info.getFile()); + getRepository().download(info.getFile(), Path.of("modules/")); + } + } + +} diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/InfoCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/InfoCommand.java new file mode 100644 index 00000000..de5a6e0a --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/modules/InfoCommand.java @@ -0,0 +1,62 @@ +package com.github.thmarx.cms.cli.commands.modules; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +import com.github.thmarx.cms.cli.commands.themes.AbstractThemeCommand; +import com.github.thmarx.cms.CMSServer; +import com.github.thmarx.cms.extensions.repository.RemoteRepository; +import lombok.Setter; +import picocli.CommandLine; + +/** + * + * @author t.marx + */ +@CommandLine.Command(name = "info") +public class InfoCommand extends AbstractThemeCommand implements Runnable { + + @CommandLine.Parameters( + paramLabel = "", + index = "0", + description = "The id of the module." + ) + @Setter + private String module = ""; + + @Override + public void run() { + if (!getRepository().exists(module)) { + throw new RuntimeException("Module not available"); + } + var info = getRepository().getInfo(module).get(); + + System.out.println("module: " + info.getId()); + System.out.println("name: " + info.getName()); + System.out.println("description: " + info.getDescription()); + System.out.println("author: " + info.getAuthor()); + System.out.println("url: " + info.getUrl()); + System.out.println("file: " + info.getFile()); + System.out.println("compatibility: " + info.getCompatibility()); + System.out.println("your server version: " + CMSServer.getVersion().getVersion()); + System.out.println("compatibility with server version: " + CMSServer.getVersion().satisfies(info.getCompatibility())); + } +} diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/AbstractThemeCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/AbstractThemeCommand.java new file mode 100644 index 00000000..5136b739 --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/AbstractThemeCommand.java @@ -0,0 +1,49 @@ +package com.github.thmarx.cms.cli.commands.themes; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.github.thmarx.cms.CMSServer; +import com.github.thmarx.cms.extensions.repository.ModuleInfo; +import com.github.thmarx.cms.extensions.repository.RemoteModuleRepository; +import lombok.Getter; + +/** + * + * @author t.marx + */ +public abstract class AbstractThemeCommand { + + public static final String DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/thmarx/theme-registry"; + + @Getter + private RemoteModuleRepository repository = new RemoteModuleRepository(ModuleInfo.class, DEFAULT_REGISTRY_URL); + + public boolean isCompatibleWithServer(String extension) { + var info = repository.getInfo(extension); + if (info.isEmpty()) { + throw new RuntimeException("theme not found"); + } + + return CMSServer.getVersion().satisfies(info.get().getCompatibility()); + } +} diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/GetCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/GetCommand.java new file mode 100644 index 00000000..629481ca --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/GetCommand.java @@ -0,0 +1,62 @@ +package com.github.thmarx.cms.cli.commands.themes; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.github.thmarx.cms.CMSServer; +import java.nio.file.Path; +import lombok.extern.slf4j.Slf4j; +import picocli.CommandLine; + +/** + * + * @author t.marx + */ +@Slf4j +@CommandLine.Command(name = "get") +public class GetCommand extends AbstractThemeCommand implements Runnable { + + @CommandLine.Parameters( + paramLabel = "", + index = "0", + description = "The id of the theme." + ) + private String theme = ""; + + @Override + public void run() { + + if (getRepository().exists(theme)) { + + if (!isCompatibleWithServer(theme)) { + throw new RuntimeException("theme is not compatible with server version"); + } + + var info = getRepository().getInfo(theme).get(); + + System.out.println("get theme"); + System.out.println("from: " + info.getFile()); + getRepository().download(info.getFile(), Path.of("themes/")); + } + } + +} diff --git a/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/InfoCommand.java b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/InfoCommand.java new file mode 100644 index 00000000..6093ca2c --- /dev/null +++ b/cms-server/src/main/java/com/github/thmarx/cms/cli/commands/themes/InfoCommand.java @@ -0,0 +1,61 @@ +package com.github.thmarx.cms.cli.commands.themes; + +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ +import com.github.thmarx.cms.CMSServer; +import com.github.thmarx.cms.extensions.repository.RemoteRepository; +import lombok.Setter; +import picocli.CommandLine; + +/** + * + * @author t.marx + */ +@CommandLine.Command(name = "info") +public class InfoCommand extends AbstractThemeCommand implements Runnable { + + @CommandLine.Parameters( + paramLabel = "", + index = "0", + description = "The id of the module." + ) + @Setter + private String module = ""; + + @Override + public void run() { + if (!getRepository().exists(module)) { + throw new RuntimeException("Module not available"); + } + var info = getRepository().getInfo(module).get(); + + System.out.println("module: " + info.getId()); + System.out.println("name: " + info.getName()); + System.out.println("description: " + info.getDescription()); + System.out.println("author: " + info.getAuthor()); + System.out.println("url: " + info.getUrl()); + System.out.println("file: " + info.getFile()); + System.out.println("compatibility: " + info.getCompatibility()); + System.out.println("your server version: " + CMSServer.getVersion().getVersion()); + System.out.println("compatibility with server version: " + CMSServer.getVersion().satisfies(info.getCompatibility())); + } +} diff --git a/cms-server/src/test/java/com/github/thmarx/cms/cli/commands/extensions/InfoCommandTest.java b/cms-server/src/test/java/com/github/thmarx/cms/cli/commands/extensions/InfoCommandTest.java index 9403a5ef..f9c648df 100644 --- a/cms-server/src/test/java/com/github/thmarx/cms/cli/commands/extensions/InfoCommandTest.java +++ b/cms-server/src/test/java/com/github/thmarx/cms/cli/commands/extensions/InfoCommandTest.java @@ -1,5 +1,27 @@ package com.github.thmarx.cms.cli.commands.extensions; +/*- + * #%L + * cms-server + * %% + * Copyright (C) 2023 - 2024 Marx-Software + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + * #L% + */ + import org.junit.jupiter.api.Test; /** diff --git a/cms-server/themes/demo/theme.yaml b/cms-server/themes/demo/theme.yaml index 828a0194..eb17806d 100644 --- a/cms-server/themes/demo/theme.yaml +++ b/cms-server/themes/demo/theme.yaml @@ -3,9 +3,7 @@ template: engine: thymeleaf modules: active: - - example-module - thymeleaf-module - - search-module media: formats: - name: small diff --git a/distribution/build.xml b/distribution/build.xml index 17389abe..ca357daf 100644 --- a/distribution/build.xml +++ b/distribution/build.xml @@ -1,25 +1,16 @@ - 4.18.1 + 4.19.0 v1.1.0 v1.1.0 v2.2.0 - v1.2.0 - v1.2.0 - v1.2.0 download template implementation modules - download seo module - - download search module - - download forms module - @@ -27,9 +18,6 @@ - - -