Compare commits

...

10 Commits

Author SHA1 Message Date
06e8949b8e migrated to Gitea
All checks were successful
CI / build (push) Successful in 53s
2024-04-14 19:12:18 +08:00
1890d1d7b5 updated lys version 2024-03-11 21:26:59 +08:00
ca1b378a14 use khtml library 2024-03-01 06:10:54 +08:00
f48a201406 removed Content-Length from downloadTar API as it would lead to file truncation 2024-02-27 05:12:15 +08:00
5e7f0b179b added Gradle caching 2024-02-24 18:19:41 +08:00
1a708699f5 updated Jenkinsfile 2024-02-24 18:17:19 +08:00
ec29250ca9 embedded Bootstrap inside webpack 2024-02-24 17:56:30 +08:00
ae0e4de23e updated client 2024-02-22 08:50:19 +08:00
b1a7bcc9a8 fixed client 2024-02-21 08:59:39 +08:00
b1297b3194 removed Nim source 2024-02-21 08:54:21 +08:00
35 changed files with 285 additions and 749 deletions

View File

@@ -0,0 +1,20 @@
name: CI
on:
push:
branches: [ master ]
jobs:
build:
runs-on: woryzen
steps:
- name: Checkout sources
uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Execute Gradle build
env:
PUBLISHER_TOKEN: ${{ secrets.PUBLISHER_TOKEN }}
run: ./gradlew build publish

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "nim/lib/htmlutils"]
path = nim/lib/htmlutils
url = git.woggioni.net:htmlutils

5
Jenkinsfile vendored
View File

@@ -19,5 +19,10 @@ pipeline {
}
}
}
post {
always {
cleanWs deleteDirs: true, skipWhenFailed: true
}
}
}

View File

@@ -37,7 +37,7 @@ allprojects {
repositories {
maven {
url = 'https://woggioni.net/mvn/'
url = getProperty('gitea.maven.url')
content {
includeGroup 'net.woggioni'
includeGroup 'com.lys'
@@ -119,18 +119,17 @@ dependencies {
Provider<War> warTaskProvider = tasks.named('war', War) { War it ->
from(configurations.frontend)
archiveVersion = ''
}
tasks.named('deploy2Wildfly', Deploy2WildflyTask) { d2w ->
d2w.rpcPort = 9990
d2w.rpcUsername = 'woggioni'
// d2w.rpcUsername = 'woggioni'
// d2w.rpcUsername = 'admin'
d2w.rpcPassword = '123456'
// d2w.rpcPassword = '123456'
d2w.deploymentName = 'jpacrepo.war'
}
File warPath = tasks.named("war", War).get().archiveFile.get().getAsFile()
tasks.named("test", Test) {
jvmArgs = [
'--add-opens', 'java.naming/javax.naming.spi=ALL-UNNAMED',
@@ -142,9 +141,20 @@ tasks.named("test", Test) {
}
publishing {
repositories {
maven {
url = 'https://mvn.woggioni.net/'
name = "Gitea"
url = uri(getProperty('gitea.maven.url'))
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = "token ${System.getenv()["PUBLISHER_TOKEN"]}"
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
publications {

View File

@@ -1,3 +1,8 @@
jpacrepo.version=2024.02.12
org.gradle.parallel=true
org.gradle.caching=true
lys.version=2024.02.12
jpacrepo.version=2024.04.14
lys.version=2024.04.14
gitea.maven.url=https://gitea.woggioni.net/api/packages/woggioni/maven

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

14
gradlew vendored
View File

@@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -202,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

20
gradlew.bat vendored
View File

@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

View File

@@ -1,6 +1,7 @@
plugins {
id 'java-library'
alias(catalog.plugins.envelope)
alias(catalog.plugins.sambal)
}
import net.woggioni.gradle.envelope.EnvelopeJarTask
@@ -10,6 +11,7 @@ dependencies {
implementation project(':jpacrepo-api')
implementation catalog.slf4j.api
implementation catalog.log4j.slf4j.impl
implementation catalog.picocli
runtimeOnly catalog.jboss.ejb.client
@@ -20,21 +22,21 @@ java {
}
tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompile) {
options.javaModuleMainClass = 'net.woggioni.jpacrepo.client.Main'
options.javaModuleMainClass = 'net.woggioni.jpacrepo.client.JpacrepoCli'
// options.compilerArgs += [
// '--add-reads', 'javax.ejb=ALL-UNNAMED'
// ]
}
Provider<EnvelopeJarTask> envelopeJarTaskProvider = tasks.named('envelopeJar', EnvelopeJarTask.class) {
mainClass = 'net.woggioni.jpacrepo.client.Main'
mainClass = 'net.woggioni.jpacrepo.client.JpacrepoCli'
}
tasks.register('run', JavaExec) { JavaExec t ->
classpath(project.sourceSets.main.output.dirs)
classpath(project.sourceSets.main.runtimeClasspath)
mainModule = 'net.woggioni.jpacrepo.client'
mainClass = 'net.woggioni.jpacrepo.client.Main'
mainClass = 'net.woggioni.jpacrepo.client.JpacrepoCli'
// String modulePath = project.sourceSets.main.runtimeClasspath.files.stream()
// .map(File::toString)
// .collect(Collectors.joining(System.getProperty('path.separator')))

View File

@@ -5,4 +5,5 @@ module net.woggioni.jpacrepo.client {
requires org.slf4j;
requires org.apache.logging.log4j;
requires net.woggioni.jpacrepo.api;
requires info.picocli;
}

View File

@@ -0,0 +1,51 @@
package net.woggioni.jpacrepo.client;
import lombok.SneakyThrows;
import picocli.CommandLine;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Objects;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
abstract class AbstractVersionProvider implements CommandLine.IVersionProvider {
private final String version;
private final String vcsHash;
@SneakyThrows
protected AbstractVersionProvider(String specificationTitle) {
String version = null;
String vcsHash = null;
Enumeration<URL> it = getClass().getClassLoader().getResources(JarFile.MANIFEST_NAME);
while (it.hasMoreElements()) {
URL manifestURL = it.nextElement();
Manifest mf = new Manifest();
try (InputStream is = manifestURL.openStream()) {
mf.read(is);
}
Attributes mainAttributes = mf.getMainAttributes();
if (Objects.equals(specificationTitle, mainAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE))) {
version = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
vcsHash = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
}
}
if (version == null || vcsHash == null) {
throw new RuntimeException("Version information not found in manifest");
}
this.version = version;
this.vcsHash = vcsHash;
}
@Override
public String[] getVersion() {
if (version.endsWith("-SNAPSHOT")) {
return new String[] { version, vcsHash };
} else {
return new String[] { version };
}
}
}

View File

@@ -0,0 +1,111 @@
package net.woggioni.jpacrepo.client;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.woggioni.jpacrepo.api.service.FileSystemSynchronizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import java.util.Properties;
class VersionProvider extends AbstractVersionProvider {
protected VersionProvider() {
super(("jpacrepo-client"));
}
}
@Slf4j
@CommandLine.Command(
name = "jpacrepo-cli",
versionProvider = VersionProvider.class)
public class JpacrepoCli implements Runnable {
@CommandLine.Option(
names = {"-ssl", "--tls"},
description = "Connect using SSL/TLS"
)
private boolean ssl = false;
@CommandLine.Option(
names = {"-H", "--host"},
description = "Wildfly server hostname"
)
private String host = "localhost";
@CommandLine.Option(
names = {"-P", "--port"},
description = "Wildfly server RPC port"
)
private int port = 8080;
@CommandLine.Option(
required = true,
names = {"-u", "--user"},
description = "Wildfly RPC username"
)
private String rpcUsername;
@CommandLine.Option(
required = true,
names = {"-p", "--password"},
description = "Wildfly RPC password"
)
private String rpcPassword;
private static void traverseJndiNode(String nodeName, Context context) {
try {
NamingEnumeration<NameClassPair> list = context.list(nodeName);
while (list.hasMore()) {
String childName = nodeName + "" + list.next().getName();
System.out.println(childName);
traverseJndiNode(childName, context);
}
} catch (NamingException ex) {
// We reached a leaf
}
}
@SneakyThrows
private Context createContext() {
Properties prop = new Properties();
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
if(ssl) {
prop.put(Context.PROVIDER_URL, String.format("remote+https://%s:%d", host, port));
} else {
prop.put(Context.PROVIDER_URL, String.format("http-remoting://%s:%d", host, port));
}
prop.put(Context.SECURITY_PRINCIPAL, rpcUsername);
prop.put(Context.SECURITY_CREDENTIALS, rpcPassword);
prop.put("jboss.naming.client.ejb.context", true);
return new InitialContext(prop);
}
@SneakyThrows
@Override
public void run() {
Context ctx = createContext();
// traverseJndiNode("/", context);
final FileSystemSynchronizer service = (FileSystemSynchronizer) ctx.lookup(
"/jpacrepo/PackageSynchronizerEJB!net.woggioni.jpacrepo.api.service.FileSystemSynchronizer"
);
service.syncDb();
}
public static void main(String[] args) {
Logger log = LoggerFactory.getLogger("jpacrepo-cli");
CommandLine commandLine = new CommandLine(new JpacrepoCli());
commandLine.setExecutionExceptionHandler((ex, cl, parseResult) -> {
log.error(ex.getLocalizedMessage(), ex);
return CommandLine.ExitCode.SOFTWARE;
});
System.exit(commandLine.execute(args));
}
}

View File

@@ -1,58 +0,0 @@
package net.woggioni.jpacrepo.client;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.woggioni.jpacrepo.api.service.PacmanServiceRemote;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import java.util.Properties;
@Slf4j
public class Main {
private static void traverseJndiNode(String nodeName, Context context) {
try {
NamingEnumeration<NameClassPair> list = context.list(nodeName);
while (list.hasMore()) {
String childName = nodeName + "" + list.next().getName();
System.out.println(childName);
traverseJndiNode(childName, context);
}
} catch (NamingException ex) {
// We reached a leaf
}
}
@SneakyThrows
public static void main(String[] args) {
Properties prop = new Properties();
// InputStream in = Main.class.getClassLoader().getResourceAsStream("jboss-ejb-client.properties");
// prop.load(in);
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
prop.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
// prop.put(Context.PROVIDER_URL, "http-remoting://nuc:8080");
// prop.put(Context.PROVIDER_URL, "remote://odroid-u3:4447");
prop.put(Context.SECURITY_PRINCIPAL, "walter");
prop.put(Context.SECURITY_CREDENTIALS, "27ff5990757d1d");
// prop.put(Context.SECURITY_PRINCIPAL, "luser");
// prop.put(Context.SECURITY_CREDENTIALS, "123456");
prop.put("jboss.naming.client.ejb.context", true);
Context context = new InitialContext(prop);
Context ctx = new InitialContext(prop);
traverseJndiNode("/", context);
// final PacmanService stateService = (PacmanService) ctx.lookup("/jpacrepo-1.0/remote/PacmanServiceEJB!service.PacmanService");
final PacmanServiceRemote service = (PacmanServiceRemote) ctx.lookup(
"/jpacrepo-2.0-SNAPSHOT/PacmanServiceEJB!net.woggioni.jpacrepo.api.service.PacmanServiceRemote"
);
// List<PkgData> pkgs = service.searchPackage("google-earth", null, null, 1, 10);
// System.out.println(new XStream().toXML(pkgs));
service.syncDB();
}
}

View File

@@ -1,11 +0,0 @@
package net.woggioni.jpacrepo.experimental;
import org.junit.jupiter.api.Test;
public class JPQLTest {
@Test
public void test() {
}
}

View File

@@ -1,6 +1,6 @@
plugins {
alias(catalog.plugins.kotlin.multiplatform)
id "org.jetbrains.kotlin.plugin.serialization" version "1.9.22"
alias(catalog.plugins.kotlin.serialization)
}
@@ -18,11 +18,16 @@ kotlin {
jsMain {
dependencies {
implementation catalog.klevtree
implementation catalog.khtml
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-serialization-json', version: '1.6.2'
// implementation(npm("bootstrap", "5.3.2"))
// implementation(npm("bootstrap-icons", "1.11.3"))
// implementation(npm("style-loader", "3.3.4"))
// implementation(npm("css-loader", "6.10.0"))
implementation(npm("bootstrap", "5.3.2"))
implementation(npm("bootstrap-icons", "1.11.3"))
implementation(npm("style-loader", "3.3.4"))
implementation(npm("css-loader", "6.10.0"))
implementation(npm("postcss-loader", "8.1.0"))
implementation(npm("sass", "1.71.1"))
implementation(npm("sass-loader", "14.1.1"))
}
}
}
@@ -30,7 +35,10 @@ kotlin {
browser {
runTask {
sourceMaps = true
devServer.port = 8080
devServer.port = 5080
cssSupport {
enabled.set(false)
}
}
webpackTask {
sourceMaps = false

View File

@@ -1,182 +0,0 @@
package net.woggioni.jpacrepo
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.startCoroutine
import kotlin.coroutines.suspendCoroutine
import kotlin.js.Promise
import org.w3c.dom.Document
import org.w3c.dom.Element
import org.w3c.dom.events.Event
object HtmlUtils {
fun Element.removeChildren() {
while (true) {
removeChild(firstChild ?: break)
}
}
fun Element.on(eventName : String, eventListener : (Event) -> Unit) {
addEventListener(eventName, eventListener)
}
fun launch(block: suspend () -> Unit) {
block.startCoroutine(object : Continuation<Unit> {
override val context: CoroutineContext get() = EmptyCoroutineContext
override fun resumeWith(result: Result<Unit>) {}
})
}
suspend fun <T> Promise<T>.await(): T = suspendCoroutine { cont ->
then({ cont.resume(it) }, { cont.resumeWithException(it) })
}
}
class HtmlBuilder private constructor(private val doc : Document, val el: Element) {
companion object {
fun <T> of(doc : Document, el: Element, cb : HtmlBuilder.(el : Element) -> T) : T {
return HtmlBuilder(doc, el).cb(el)
}
}
private inline fun <T> dfd(
name : String,
attrs : Map<String, String>,
cb : HtmlBuilder.(el : Element) -> T) : T {
val child = doc.createElement(name)
for((key, value) in attrs) {
child.setAttribute(key, value)
}
el.appendChild(child)
return HtmlBuilder(doc, child).cb(child)
}
fun <T> html(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("html", attrs, cb)
fun <T> head(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("head", attrs, cb)
fun <T> body(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("body", attrs, cb)
fun <T> use(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("use", attrs, cb)
fun <T> svg(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("svg", attrs, cb)
fun <T> div(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("div", attrs, cb)
fun <T> header(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("header", attrs, cb)
fun <T> main(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("main", attrs, cb)
fun <T> footer(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("footer", attrs, cb)
fun <T> a(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("a", attrs, cb)
fun <T> meta(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("meta", attrs, cb)
fun <T> script(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("script", attrs, cb)
fun <T> link(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("link", attrs, cb)
fun <T> title(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("title", attrs, cb)
fun <T> p(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("p", attrs, cb)
fun <T> span(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("span", attrs, cb)
fun <T> i(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("i", attrs, cb)
fun <T> del(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("del", attrs, cb)
fun <T> s(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("s", attrs, cb)
fun <T> ins(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("ins", attrs, cb)
fun <T> u(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("u", attrs, cb)
fun <T> b(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("b", attrs, cb)
fun <T> small(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("small", attrs, cb)
fun <T> strong(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("strong", attrs, cb)
fun <T> em(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("em", attrs, cb)
fun <T> mark(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("mark", attrs, cb)
fun <T> obj(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("object", attrs, cb)
fun <T> h1(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("h1", attrs, cb)
fun <T> h2(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("h2", attrs, cb)
fun <T> h3(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("h3", attrs, cb)
fun <T> h4(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("h4", attrs, cb)
fun <T> h5(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("h5", attrs, cb)
fun <T> h6(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("h6", attrs, cb)
fun <T> table(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("table", attrs, cb)
fun <T> thead(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("thead", attrs, cb)
fun <T> tbody(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("tbody", attrs, cb)
fun <T> tfoot(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("tfoot", attrs, cb)
fun <T> tr(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("tr", attrs, cb)
fun <T> th(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("th", attrs, cb)
fun <T> td(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("td", attrs, cb)
fun <T> ol(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("ol", attrs, cb)
fun <T> ul(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("ul", attrs, cb)
fun <T> li(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("li", attrs, cb)
fun <T> img(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("img", attrs, cb)
fun <T> form(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("form", attrs, cb)
fun <T> label(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("label", attrs, cb)
fun <T> button(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("button", attrs, cb)
fun <T> input(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("input", attrs, cb)
fun <T> select(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("select", attrs, cb)
fun <T> option(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("option", attrs, cb)
fun <T> meter(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("meter", attrs, cb)
fun <T> nav(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("nav", attrs, cb)
fun <T> menu(attrs : Map<String, String> = emptyMap(),
cb : HtmlBuilder.(el : Element) -> T) : T = dfd("menu", attrs, cb)
fun classes(vararg classes : String) {
for(cls in classes) el.classList.add(cls)
}
fun attr(key: String, value : String) {
el.setAttribute(key, value)
}
fun text(txt : String) {
el.appendChild(doc.createTextNode(txt))
}
fun on(eventName : String, cb: (Event) -> Unit) {
el.addEventListener(eventName, cb)
}
}

View File

@@ -6,11 +6,12 @@ import kotlinx.browser.document
import kotlinx.browser.window
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import net.woggioni.jpacrepo.HtmlUtils.await
import net.woggioni.jpacrepo.HtmlUtils.launch
import net.woggioni.jpacrepo.HtmlUtils.on
import net.woggioni.jpacrepo.HtmlUtils.removeChildren
import net.woggioni.jpacrepo.common.JpacrepoCommons.toHexString
import net.woggioni.khtml.Khtml
import net.woggioni.khtml.Khtml.Companion.await
import net.woggioni.khtml.Khtml.Companion.launch
import net.woggioni.khtml.Khtml.Companion.on
import net.woggioni.khtml.Khtml.Companion.removeChildren
import net.woggioni.klevtree.LevTrie
import org.w3c.dom.CustomEvent
import org.w3c.dom.Element
@@ -132,7 +133,7 @@ suspend fun buildTable(root: Element, searchTerm: String, commonElement: Element
while (children.length > 0) {
children[0]!!.remove()
}
HtmlBuilder.of(document, root) {
Khtml.of(document, root) {
table {
classes("table", "table-striped", "pkgtable")
thead {
@@ -209,9 +210,9 @@ suspend fun buildTable(root: Element, searchTerm: String, commonElement: Element
?.let { it[selectedVersion] }
availablePackages?.keys?.first()
}
var selectedCompressionFormat = getFirstAvailableCompressionFormat()
var selectedCompressionFormat: CompressionFormat?
fun HtmlBuilder.createCompressionFormatDropdown() {
fun Khtml.createCompressionFormatDropdown() {
val availablePackages = packages
?.let { it[selectedVersion] }
availablePackages?.keys?.let { compressionFormats ->
@@ -236,24 +237,21 @@ suspend fun buildTable(root: Element, searchTerm: String, commonElement: Element
val compressionFormatCell = td {
createCompressionFormatDropdown()
el
}
val fileNameCell = td {
selectedPackage?.let {
text(it.second.fileName)
}
el
}
val sizeCell = td {
selectedPackage?.let {
text(it.second.size.toHumanReadableByteSize())
}
el
}
on(REFRESH_TABLE_ROW_EVENT_NAME) { evt ->
on(REFRESH_TABLE_ROW_EVENT_NAME) {
selectedCompressionFormat = getFirstAvailableCompressionFormat()
compressionFormatCell.removeChildren()
HtmlBuilder.of(document, compressionFormatCell) {
Khtml.of(document, compressionFormatCell) {
createCompressionFormatDropdown()
}
selectedPackage = archive.pkgMap[arch]?.let {
@@ -278,9 +276,9 @@ suspend fun buildTable(root: Element, searchTerm: String, commonElement: Element
}
}
private fun HtmlBuilder.buildPackageSearchSection(commonElement: Element) {
val root = el
private fun Khtml.buildPackageSearchSection(commonElement: Element) {
var selectedPackageName: String? = null
val root = element
div {
classes("row", "g-5")
div {
@@ -354,7 +352,7 @@ private fun HtmlBuilder.buildPackageSearchSection(commonElement: Element) {
}
div { table ->
classes("row", "align-items-md-stretch")
root.on(REFRESH_TABLE_EVENT_NAME) { evt ->
root.on(REFRESH_TABLE_EVENT_NAME) { evt : Event ->
launch {
(evt as? CustomEvent)?.let { pnuv ->
table.let { t ->
@@ -370,7 +368,8 @@ private fun HtmlBuilder.buildPackageSearchSection(commonElement: Element) {
}
fun main(vararg args: String) {
HtmlBuilder.of(document, document.body as HTMLElement) {
js("require ('./scss/styles.scss');")
Khtml.of(document, document.body as HTMLElement) {
main { main ->
div {
classes("container", "py-4")
@@ -391,7 +390,7 @@ fun main(vararg args: String) {
div {
classes("container")
div {
val commonElement = el
val commonElement = element
classes("row", "align-items-start")
div {
classes("col-3")
@@ -404,7 +403,7 @@ fun main(vararg args: String) {
text("Package Cart")
}
}
fun HtmlBuilder.createSelectedPackageList() {
fun Khtml.createSelectedPackageList() {
if (selectedPackages.isNotEmpty()) {
div {
classes("card-body")
@@ -432,7 +431,7 @@ fun main(vararg args: String) {
}
button {
classes("btn", "btn-primary", "w-100")
el.asDynamic().style.marginTop = "10px"
element.asDynamic().style.marginTop = "10px"
val totalSize = selectedPackages
.asSequence()
.map(PkgTuple::size)
@@ -452,9 +451,9 @@ fun main(vararg args: String) {
.map(PkgTuple::fileName)
.joinToString(" ")
temporaryForm.appendChild(textField)
el.appendChild(temporaryForm)
element.appendChild(temporaryForm)
temporaryForm.submit()
el.removeChild(temporaryForm)
element.removeChild(temporaryForm)
}
}
}
@@ -463,7 +462,7 @@ fun main(vararg args: String) {
div {
createSelectedPackageList()
commonElement.on(REFRESH_SELECTED_PACKAGES_EVENT_NAME) {
el.removeChildren()
element.removeChildren()
createSelectedPackageList()
}
}
@@ -473,7 +472,6 @@ fun main(vararg args: String) {
classes("col-9")
buildPackageSearchSection(commonElement)
}
el
}
}
footer {

View File

@@ -4,15 +4,7 @@
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="css/jpacrepo.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
crossorigin="anonymous"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
crossorigin="anonymous"></script>
<script src="jpacrepo-frontend.js" defer="true"></script>
<title>Hello World!</title>
<title>Jpacrepo</title>
</head>
</html>

View File

@@ -0,0 +1,2 @@
@import "bootstrap/scss/bootstrap";
@import "bootstrap-icons/font/bootstrap-icons.min.css";

View File

@@ -0,0 +1,3 @@
config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'});
config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'});
config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, type: 'asset/resource'});

View File

@@ -0,0 +1 @@
config.module.rules.push({ test: /\.css$/, use: ["style-loader", { loader: "css-loader", options: {sourceMap: false} } ] });

View File

@@ -0,0 +1,2 @@
config.module.rules.push({ test: /\.s[ac]ss$/, use: ["style-loader", { loader: "css-loader", options: {sourceMap: false} }, "sass-loader" ] });

View File

@@ -1,5 +0,0 @@
#!/usr/bin/env nim
task build, "builds an example":
setCommand "js"
#os.copyfile("")

View File

@@ -1,4 +0,0 @@
#!/bin/bash
set -e
nim js src/jpacrepo.nim
cp nimcache/jpacrepo.js static

View File

@@ -1 +0,0 @@
path="lib/htmlutils/src"

View File

@@ -1,375 +0,0 @@
import dom
import htmlutils/tree
import htmlutils/utils
import json
import tables
import strutils
import sets
from sequtils import map, apply
var pkgMap : JsonNode
const serverURL {.strdefine.}: string = ""
proc last[T](s : seq[T]) : T = s[s.len - 1]
proc formatByteSize(size : BiggestInt) : string = size.float64.formatEng(precision=1, siPrefix=true, unit = "B")
type DownloadPanel = ref object
badge : Element
listgroup : Element
pkgs : HashSet[string]
footer : Element
sizeLabel : Element
size : BiggestInt
proc newDownloadPanel(parent : Element) : DownloadPanel =
let dp = DownloadPanel()
dp.pkgs = initHashSet[string]()
htmlTreeAppend(parent):
"div":
classList = ["panel", "panel-default"]
"div":
classList = ["panel-heading"]
"h3":
classList = ["panel-title"]
"a":
text = "Package list "
"span":
classList = ["badge", "pull-right"]
style {"display" :"none"}
cb:
dp.badge = elem
"ul":
classList = ["list-group"]
cb:
dp.listgroup = elem
"div":
classList = ["panel-footer"]
style = {
"text-align" : "right",
"display" :"none"
}
"span":
style = {
"font-weight" : "bold",
"padding-right" : "10px"
}
cb:
dp.sizeLabel = elem
"button":
classList = ["btn", "btn-primary"]
attrs = {"type" : "button"}
"span":
classList = ["glyphicon", "glyphicon-download"]
cb:
elem.appendChild(document.createTextNode(" Download"))
let clickHandler = proc(e : Event) =
let pkglist : seq[string] = sequtils.toSeq(dp.pkgs.items())
let form = cast[Formelement](document.createElement("form"))
form.style.display = "none"
form.setAttribute("method", "post")
form.setAttribute("action", serverURL & "api/pkg/downloadTar")
let tf= document.createElement("input")
tf.setAttribute("name", "pkgs")
let txt = sequtils.foldl(pkglist, a & " " & b)
echo txt
tf.value(txt)
form.appendChild(tf)
document.body.appendChild(form)
form.submit()
elem.addEventListener("click", clickHandler)
cb:
dp.footer = elem
dp
proc updateBadge(dp : DownloadPanel) =
let st = if dp.pkgs.len() > 0: "block" else: "none"
dp.footer.style.display = st
dp.badge.style.display = st
dp.badge.textContent = $dp.pkgs.len()
proc updateSize(dp : DownloadPanel) =
dp.sizeLabel.textContent = "Total: " & dp.size.formatByteSize
proc addPkg(dp : DownloadPanel, pkgfile : string) =
if not dp.pkgs.contains(pkgfile):
dp.pkgs.incl(pkgfile)
let req = newXMLHTTPRequest()
let load_cb = proc(e : Event) =
let sz = parseInt($req.responseText)
dp.size += sz
dp.updateSize
htmlTreeAppend(dp.listgroup):
"li":
var listElement : Element
classList = ["list-group-item"]
text = pkgfile
"span":
classList = ["glyphicon", "glyphicon-remove", "pull-right"]
cb:
let fn = proc(e : Event) =
dp.pkgs.excl(pkgfile)
listElement.remove()
dp.updateBadge
dp.size -= sz
dp.updateSize
elem.addEventListener("click", fn)
cb:
listElement = elem
req.addEventListener("load", load_cb)
req.open("get", serverURL & "api/pkg/filesize/" & pkgfile)
req.setRequestHeader("Accept", "application/json")
req.send()
dp.updateBadge
proc readTableRow(arch : string, row : Element) : JsonNode =
let pkgname = $row.querySelector("td:nth-child(2)").textContent
let version = $row.querySelector("td:nth-child(3) button").textContent
let filename = $row.querySelector("td:nth-child(4) button").textContent
for candidate in pkgMap[arch][pkgname][version]:
if filename == candidate["fileName"].getStr:
return candidate
proc createDropdown(parent : Element, data :seq[string], onchange : proc(value : string)) =
htmlTreeAppend(parent):
"span":
var button : Element
classList = ["dropdown"]
"button":
classList = ["btn", "btn-default", "dropdown-toggle"]
attrs = {"data-toggle": "dropdown", "type": "button"}
cb:
elem.textContent = data[0]
button = elem
"ul":
classList = ["dropdown-menu"]
cb:
for line in data:
htmlTreeAppend(elem):
"li":
"a":
text = line
cb:
let fn = proc(e: Event) =
button.textContent = elem.textContent
onchange($elem.textContent)
elem.addEventListener("click", fn)
type PkgTable = ref object
addButton : Element
proc newPkgTable(parent: Element, arch: string, searchString : string, addButtonCallback : proc(e : Event)) : PkgTable =
var pkgtable = PkgTable()
var fragments = newSeq[string]()
for fragment in searchString.splitWhitespace():
fragments.add(fragment)
var searchResult = newOrderedTable[string, JsonNode]()
for key, value in pkgMap[arch]:
for fragment in fragments:
if fragment in key:
searchResult[key] = value
for node in parent.querySelectorAll("table.pkgtable"):
parent.removeChild(node)
htmlTreeAppend(parent):
"table":
classList = ["table", "table-striped","pkgtable"]
"thead":
"tr":
"th":
"button":
classList = ["btn", "btn-default"]
attrs = {"type": "button"}
"span":
classList = ["glyphicon", "glyphicon-plus"]
cb:
let txt = document.createTextNode(" Add")
elem.appendChild(txt)
pkgtable.addButton = elem
"th":
text = "Name"
"th":
text = "Version"
"th":
text = "File name"
"th":
text = "Installed size"
"tbody":
cb:
var i = 0
for name, versions in searchResult.mpairs:
closureScope:
htmlTreeAppend(elem):
"tr":
var row : Element
var fileNameCell : Element
var sizeCell : Element
let size_change_callback = proc(newValue : string) =
sizeCell.textContent = readTableRow(arch, row)["size"].getInt.formatByteSize
"td":
"div":
classList = ["checkbox"]
"label":
"input":
attrs = {"type" : "checkbox"}
"td":
text = $name
"td":
cb:
var data = newSeq[string]()
for version, arches in versions:
data.add(version)
let vs = versions
let change_callback = proc(newValue : string) =
fileNameCell.removeChildren()
var newdata = newSeq[string]()
for arch, pkgname in vs[newValue]:
newdata.add(arch)
createDropdown(fileNameCell, newdata, size_change_callback)
size_change_callback(newValue)
createDropdown(elem, data, change_callback)
"td":
cb:
fileNameCell = elem
var data = newSeq[string]()
var files : JsonNode
for v, f in versions:
files = f
break
for file in files:
data.add(file["fileName"].getStr)
createDropdown(elem, data, size_change_callback)
"td":
cb:
sizeCell = elem
for v, files in versions:
for file in files:
elem.textContent = file["size"].getInt.formatByteSize
return
cb:
row = elem
pkgtable.addButton.addEventListener("click", addButtonCallback)
pkgtable
var selectedArch : string
var archButtons : Element
var table : Element
var searchString : string
var add2DownloadList : proc(e : Event)
proc updateTable(e : Event) =
if pkgMap.len == 0 or searchString.len < 2: return
discard newPkgTable(table, selectedArch, searchString, add2DownloadList)
var dp : DownloadPanel
# var pkgTable : PkgTable
htmlTreeappend document.body:
# "img":
# attrs {"src" : "img/background.bpg"}
# style {
# "width" : "100%",
# "position" : "fixed",
# "bottom" : "0",
# "left" : "0",
# "z-index" : "-10"
# }
"div":
style = {"background-color" : "rgba(255, 255, 255, 0.25)"}
classList = ["container"]
"div":
style = {
"margin-top" : "20px",
"background-color" : "rgba(224, 224, 224, 0.5)"
}
classList = ["jumbotron"]
"h1":
text = "Jpacrepo"
"p":
text = "Personal archlinux package repository"
"div":
"form":
classList = ["form-horizontal"]
"div":
classList = ["form-group"]
"label":
classList = ["control-label", "col-sm-2"]
text = " Search package"
"div":
classList = ["col-sm-10"]
"input":
classList = ["form-control"]
attrs = {"type" : "text"}
cb :
add2DownloadList = proc(e : Event) =
let rows = table.querySelectorAll("tbody tr")
for row in rows:
let cbox = row.querySelector("td:first-child input")
if cbox.checked:
dp.addPkg(readTableRow(selectedArch, row)["fileName"].getStr)
oninput:
searchString = $elem.value
updateTable(event)
"div":
classList = ["row"]
"div":
classList = ["col-sm-3"]
cb:
dp = newDownloadPanel(elem)
"div":
"div":
classList = ["btn-group", "btn-group-justified"]
attrs = { "role" : "group" }
cb:
archButtons = elem
classList = ["col-sm-9"]
cb:
table = elem
let r = newXMLHTTPRequest()
let load_cb = proc(e : Event) =
pkgMap = parseJson($r.responseText)
var buttons = newSeq[Element]()
var index = 0
for arch in pkgMap.keys:
closureScope:
htmlTreeAppend(archButtons):
"div":
classList = ["btn-group"]
attrs = { "role" : "group"}
"button":
classList = ["btn", "btn-default"]
attrs = {
"type": "button",
}
text = arch
let thisButtonIndex = index
let thisButtonArch = arch
onclick:
let update = thisButtonArch != selectedArch
selectedArch = thisButtonArch
for i in 0..<buttons.len:
let btn = buttons[i]
if(i == thisButtonIndex):
btn.classList.toggle("active")
else:
btn.classList.remove("active")
if update:
updateTable(event)
cb:
buttons.add(elem)
if index == 0:
selectedArch = arch
elem.classList.add("active")
inc(index)
# createDropdown(archDropDown, data, arch_change_callback)
r.addEventListener("load", load_cb)
r.open("get", serverURL & "api/pkg/map")
r.setRequestHeader("Accept", "application/json")
r.send()

View File

@@ -1,13 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="jpacrepo.css" type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="jpacrepo.js" defer></script>
</head>
<body>
</body>
</html>

View File

@@ -1,12 +1,13 @@
pluginManagement {
repositories {
maven {
url = 'https://woggioni.net/mvn/'
url = getProperty('gitea.maven.url')
content {
includeGroup 'net.woggioni.gradle'
includeGroup 'net.woggioni.gradle.lombok'
includeGroup 'net.woggioni.gradle.wildfly'
includeGroup 'net.woggioni.gradle.envelope'
includeGroup 'net.woggioni.gradle.sambal'
}
}
gradlePluginPortal()
@@ -16,7 +17,7 @@ pluginManagement {
dependencyResolutionManagement {
repositories {
maven {
url = 'https://woggioni.net/mvn/'
url = getProperty('gitea.maven.url')
content {
includeGroup 'com.lys'
}
@@ -26,6 +27,7 @@ dependencyResolutionManagement {
catalog {
from group: 'com.lys', name: 'lys-catalog', version: getProperty('lys.version')
version("slf4j", "1.7.36")
version('jzstd', '2024.04.14')
}
}
}

View File

@@ -307,10 +307,6 @@ public class PacmanWebService {
public Response downloadTar(@FormParam("pkgs") String formData) {
String[] files = URLDecoder.decode(formData, StandardCharsets.UTF_8).split(" ");
Fun<java.nio.file.Path, Long> fun = Files::size;
long estimatedSize = Arrays.stream(files)
.map(ctx::getFile)
.mapToLong(fun::apply)
.sum();
Arrays.stream(files)
.filter(fileName -> !Files.exists(ctx.getFile(fileName)))
.forEach(fileName -> {
@@ -341,7 +337,6 @@ public class PacmanWebService {
}
};
return Response.ok(stream)
.header("Content-Length", estimatedSize)
.header("Content-Disposition", "attachment; filename=pkgs.tar")
.build();
}

View File

@@ -9,6 +9,6 @@
},
"verify-token-audience": true,
"confidential-port": 443,
"token-signature-algorithm": "ES512",
"token-signature-algorithm": "RS256",
"use-resource-role-mappings": true
}

View File

@@ -85,7 +85,6 @@ public class ClientTest {
assert Response.Status.CREATED.getStatusCode() == response.getStatus();
}
@Test
public void hashTest(@TempDir Path testDir) {
ClassLoader cl = getClass().getClassLoader();
Stream.of("gvfs-nfs-1.50.2-1-x86_64.pkg.tar.zst")
@@ -116,7 +115,6 @@ public class ClientTest {
}
}
@Test
public void invokeStatelessBean() throws Exception {
Properties prop = new Properties();
InputStream in = getClass().getClassLoader().getResourceAsStream("jboss-ejb-client.properties");
@@ -124,35 +122,18 @@ public class ClientTest {
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
// prop.put(Context.PROVIDER_URL, "http-remoting://localhost:1234");
prop.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
// prop.put(Context.PROVIDER_URL, "remote://odroid-u3:4447");
prop.put(Context.SECURITY_PRINCIPAL, "walter");
prop.put(Context.SECURITY_CREDENTIALS, "27ff5990757d1d");
// prop.put(Context.SECURITY_PRINCIPAL, "luser");
// prop.put(Context.SECURITY_CREDENTIALS, "123456");
prop.put(Context.SECURITY_PRINCIPAL, "luser");
prop.put(Context.SECURITY_CREDENTIALS, "123456");
prop.put("jboss.naming.client.ejb.context", true);
Context context = new InitialContext(prop);
Context ctx = new InitialContext(prop);
traverseJndiNode("/", context);
// final PacmanService stateService = (PacmanService) ctx.lookup("/jpacrepo-1.0/remote/PacmanServiceEJB!service.PacmanService");
final FileSystemSynchronizer service = (FileSystemSynchronizer) ctx.lookup(
"/jpacrepo/PackageSynchronizerEJB!net.woggioni.jpacrepo.api.service.FileSystemSynchronizer"
);
// List<PkgData> pkgs = service.searchPackage("google-earth", null, null, 1, 10);
// System.out.println(new XStream().toXML(pkgs));
service.syncDb();
// service.searchPkgId("jre8-openjdk", null, null, null)
// .stream()
// .map(service::getPackage)
// .filter(Objects::nonNull)
// .map(PkgData::getFileName)
// .forEach(System.out::println);
// final TestEJB service = (TestEJB) ctx.lookup(
// "/jpacrepo-2023.07TestEJBImpl!net.woggioni.jpacrepo.api.service.TestEJB"
// );
// System.out.println(service.hello());
}
}