Commit f41b906d527d5458be6e6b1ccf24d8971f2c7316

Thomas de Grivel 2025-04-07T23:34:50

ci

diff --git a/home/ci/app/controllers/rbpkg_controller.kc3 b/home/ci/app/controllers/rbpkg_controller.kc3
index bc19039..ce44f5b 100644
--- a/home/ci/app/controllers/rbpkg_controller.kc3
+++ b/home/ci/app/controllers/rbpkg_controller.kc3
@@ -1,16 +1,30 @@
 defmodule RbpkgController do
 
   def index = fn () {
+    title = "ci.kmx.io - rbpkg index"
     packages = Rbpkg.list_packages()
+    page = RbpkgView.render_index(packages)
+    body = LayoutView.render("rbpkg-index", title, page,
+      Route.rbpkg())
+    %HTTP.Response{body: body}
   }
 
-  def show_repo = fn (repo) {
-    puts("RbpkgController.show_repo(#{inspect(repo)})")
+  def show_repo = fn (repo, tree) {
+    packages = Rbpkg.list_packages()
+    if List.has?(packages, repo) do
+      title = "ci.kmx.io - rbpkg repo #{repo} #{tree}"
+      info = Rbpkg.package_info(repo, tree)
+      page = RbpkgView.render_show_repo(repo, tree, info)
+      body = LayoutView.render("rbpkg-repo", title, page,
+        Route.rbpkg(repo))
+      %HTTP.Response{body: body}
+    end
   }
 
   def route = fn (request) {
-    if Str.starts_with?(request.url, "/rbpkg/") do
-      url = Str.slice(request.url, 7, -1)
+    url = if request.url == "/rbpkg" do "/rbpkg/" else request.url end
+    if Str.starts_with?(url, "/rbpkg/") do
+      url = Str.slice(url, 7, -1)
       if Str.ends_with?(url, "/") do
         url = Str.slice(url, 0, -2)
       end
@@ -24,10 +38,10 @@ defmodule RbpkgController do
             proxy(repo, tree, host)
           else
             if [repo, tree] = ^ list do
-              show_tree(repo, tree)
+              show_repo(repo, tree)
             else
               if [repo] = ^ list do
-                show_repo(repo)
+                show_repo(repo, "master")
               end
             end
           end
diff --git a/home/ci/app/models/rbpkg.kc3 b/home/ci/app/models/rbpkg.kc3
index 67d6709..a2197c8 100644
--- a/home/ci/app/models/rbpkg.kc3
+++ b/home/ci/app/models/rbpkg.kc3
@@ -1,7 +1,12 @@
 defmodule Rbpkg do
 
   def list_packages = fn () {
-    Str.split(system(["rbpkg", "list"]), "\n")
+    List.filter(Str.split(system(["rbpkg", "list"]), "\n"),
+      fn (x) { if x != "" do x end })
+  }
+
+  def package_info = fn (repo, tree) {
+    system(["rbpkg", "info", repo, tree])
   }
 
 end
diff --git a/home/ci/app/templates/footer.html.ekc3 b/home/ci/app/templates/footer.html.ekc3
new file mode 100644
index 0000000..5388503
--- /dev/null
+++ b/home/ci/app/templates/footer.html.ekc3
@@ -0,0 +1,111 @@
+<div class="pixels-5-15">
+  <div class="container">
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-0"></div>
+    <div class="pixel pixel-0"></div>
+    <div class="pixel pixel-0"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-0"></div>
+    <div class="pixel pixel-0"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+
+    <div class="pixel pixel-0"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-0"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+    <div class="pixel pixel-1"></div>
+  </div>
+</div>
+<footer class="bg-dark">
+  <div class="container">
+    <a href="https://www.kmx.io/" target="_blank"><i class="fas fa-circle"></i> Copyright 2020-2025 kmx.io</a> &nbsp; &nbsp;
+    <a href="https://www.kmx.io/contact"><i class="fas fa-envelope"></i> Contact</a> &nbsp; &nbsp;
+    <a href="https://discord.gg/nUAr57YKsh" target="_blank"><i class="fab fa-discord"></i> Discord</a>
+    <span class="right">
+      <a href="https://git.kmx.io/kc3-lang/kc3">kc3_httpd</a>
+      <a href="https://kc3-lang.org/release/v0.1.14/">v0.1.14</a>
+    </span>
+    <div class="clear"></div>
+  </div>
+</footer>
diff --git a/home/ci/app/templates/layout.html.ekc3 b/home/ci/app/templates/layout.html.ekc3
new file mode 100644
index 0000000..60b6ff7
--- /dev/null
+++ b/home/ci/app/templates/layout.html.ekc3
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title><%= title %></title>
+    <link rel="stylesheet" href="/static/_assets/app.css"/>
+    <script defer type="text/javascript" src="/static/_assets/app.js"></script>
+    <link rel="icon" type="image/png" sizes="128x128" href="/static/_images/kmx.logo.black.128.png">
+    <link rel="icon" type="image/png" sizes="64x64" href="/static/_images/kmx.logo.black.64.png">
+    <link rel="icon" type="image/png" sizes="32x32" href="/static/_images/kmx.logo.black.32.png">
+    <link rel="icon" type="image/png" sizes="16x16" href="/static/_images/kmx.logo.black.16.png">
+    <meta property="og:url"                content="<%= url %>" />
+    <meta property="og:type"               content="article" />
+    <meta property="og:title"              content="<%= title %>" />
+    <meta property="og:description"        content="Welcome to kmx.io" />
+    <meta property="og:image"              content="https://kmx.io/static/_images/kmx.logo.text.256.png" />
+  </head>
+  <body class="<%= body_classes %>">
+    <%= raw nav %>
+    <div class="page <%= body_classes %>">
+      <%= raw page %>
+    </div>
+    <%= raw footer %>
+  </body>
+</html>
diff --git a/home/ci/app/templates/nav.html.ekc3 b/home/ci/app/templates/nav.html.ekc3
new file mode 100644
index 0000000..94c9cc5
--- /dev/null
+++ b/home/ci/app/templates/nav.html.ekc3
@@ -0,0 +1,22 @@
+<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
+  <div class="container">
+    <a class="navbar-brand" href="/">
+      <div class="kmx-logo">
+        <span><i class="fas fa-circle"></i></span> ci.kmx.io
+      </div>
+    </a>
+    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+      <span class="navbar-toggler-icon"></span>
+    </button>
+    <div class="collapse navbar-collapse" id="navbarSupportedContent">
+      <ul class="navbar-nav me-auto">
+        <li class="nav-item">
+          <a class="navbar-link" href="https://kc3-lang.org">KC3</a>
+        </li>
+        <li class="nav-item">
+          <a class="navbar-link" href="https://git.kmx.io/">kmxgit</a>
+        </li>
+      </ul>
+    </div>
+  </div>
+</nav>
diff --git a/home/ci/app/templates/rbpkg/index.html.ekc3 b/home/ci/app/templates/rbpkg/index.html.ekc3
new file mode 100644
index 0000000..2b0945c
--- /dev/null
+++ b/home/ci/app/templates/rbpkg/index.html.ekc3
@@ -0,0 +1,8 @@
+<div class="container">
+  <h1>Rbpkg index</h1>
+  <ul>
+    <%= raw List.join(List.map(packages, fn (pkg) {
+          """  <li><a href="#{HTML.escape(Route.rbpkg(pkg))}">#{HTML.escape(pkg)}</a></li>"""
+        }), "\n") %>
+  </ul>
+</div>
diff --git a/home/ci/app/templates/rbpkg/show_repo.html.ekc3 b/home/ci/app/templates/rbpkg/show_repo.html.ekc3
new file mode 100644
index 0000000..30a1a15
--- /dev/null
+++ b/home/ci/app/templates/rbpkg/show_repo.html.ekc3
@@ -0,0 +1,10 @@
+<div class="container">
+
+  <h1>
+    <a href="<%= Route.rbpkg() %>">rbpkg</a>
+    <a href="<%= Route.rbpkg(repo) %>"><%= repo %></a>
+    <a href="<%= Route.rbpkg(repo, tree) %>"><%= tree %></a>
+  </h1>
+
+  <pre><%= info %></pre>
+</div>
diff --git a/home/ci/app/views/layout_view.kc3 b/home/ci/app/views/layout_view.kc3
new file mode 100644
index 0000000..8ce817d
--- /dev/null
+++ b/home/ci/app/views/layout_view.kc3
@@ -0,0 +1,23 @@
+defmodule LayoutView do
+
+  require EKC3
+
+  def template = fn () {
+    EKC3.load("app/templates/layout.html.ekc3")
+  }
+
+  def template_footer = fn () {
+    EKC3.load("app/templates/footer.html.ekc3")
+  }
+
+  def template_nav = fn () {
+    EKC3.load("app/templates/nav.html.ekc3")
+  }
+
+  def render = fn (body_classes, title, page, url) {
+    nav = EKC3.render(template_nav())
+    footer = EKC3.render(template_footer())
+    EKC3.render(template())
+  }
+
+end
diff --git a/home/ci/app/views/rbpkg_view.kc3 b/home/ci/app/views/rbpkg_view.kc3
new file mode 100644
index 0000000..a9ac999
--- /dev/null
+++ b/home/ci/app/views/rbpkg_view.kc3
@@ -0,0 +1,19 @@
+defmodule RbpkgView do
+
+  def template_index = fn () {
+    EKC3.load("app/templates/rbpkg/index.html.ekc3")
+  }
+
+  def render_index = fn (packages) {
+    EKC3.render(template_index())
+  }
+
+  def template_show_repo = fn () {
+    EKC3.load("app/templates/rbpkg/show_repo.html.ekc3")
+  }
+
+  def render_show_repo = fn (repo, tree, info) {
+    EKC3.render(template_show_repo())
+  }
+
+end
diff --git a/home/ci/config/route.kc3 b/home/ci/config/route.kc3
deleted file mode 100644
index 4b7c42e..0000000
--- a/home/ci/config/route.kc3
+++ /dev/null
@@ -1,19 +0,0 @@
-def HTTPd.routes = []
-
-def_route("/rbpkg/", RbpkgController.route)
-
-#def_route("/sitemap.xml", SitemapController.route)
-
-HTTPd.Route.def_static_route("", "./static/", 0)
-
-defmodule Route do
-
-  def rbpkg = fn {
-    () { "/rbpkg" }
-    (repo) { "/rbpkg/#{URL.escape(repo)}" }
-    (repo, tree) { "/rbpkg/#{URL.escape(repo)}/#{URL.escape(tree)}" }
-    (repo, tree, host) { "/rbpkg/#{URL.escape(repo)}/#{URL.escape(tree)}/host/#{URL.escape(host)}" }
-    (repo, tree, host, query) { "/rbpkg/#{URL.escape(repo)}/#{URL.escape(tree)}/host/#{URL.escape(host)}/#{URL.escape(query)}" }
-  }
-
-end
diff --git a/home/ci/config/routes.kc3 b/home/ci/config/routes.kc3
index 4b7c42e..b6479cf 100644
--- a/home/ci/config/routes.kc3
+++ b/home/ci/config/routes.kc3
@@ -4,7 +4,7 @@ def_route("/rbpkg/", RbpkgController.route)
 
 #def_route("/sitemap.xml", SitemapController.route)
 
-HTTPd.Route.def_static_route("", "./static/", 0)
+HTTPd.Route.def_static_route("", "static/", 0)
 
 defmodule Route do
 
diff --git a/home/ci/static/_images/kmx.logo.black.128.png b/home/ci/static/_images/kmx.logo.black.128.png
new file mode 100644
index 0000000..64c46de
Binary files /dev/null and b/home/ci/static/_images/kmx.logo.black.128.png differ
diff --git a/home/ci/static/_images/kmx.logo.black.16.png b/home/ci/static/_images/kmx.logo.black.16.png
new file mode 100644
index 0000000..18be135
Binary files /dev/null and b/home/ci/static/_images/kmx.logo.black.16.png differ
diff --git a/home/ci/static/static b/home/ci/static/static
new file mode 120000
index 0000000..945c9b4
--- /dev/null
+++ b/home/ci/static/static
@@ -0,0 +1 @@
+.
\ No newline at end of file