10 changed files with 6621 additions and 5 deletions
@ -1,4 +1,5 @@ |
|||||||
ssg/dist-newstyle |
ssg/dist-newstyle |
||||||
src/_cache |
src/_cache |
||||||
src/_site |
src/_site |
||||||
|
src/elm-stuff |
||||||
result |
result |
||||||
|
@ -0,0 +1,99 @@ |
|||||||
|
|
||||||
|
module ServicesTable exposing (main) |
||||||
|
|
||||||
|
import List |
||||||
|
import Browser |
||||||
|
import Html exposing (Html, div, span, text, table, thead, tbody, tr, th, td) |
||||||
|
import Html.Attributes exposing (class) |
||||||
|
import Http |
||||||
|
import Dict exposing (Dict) |
||||||
|
import Json.Decode exposing (Decoder, map, map3, field, list, string, dict, keyValuePairs) |
||||||
|
|
||||||
|
type alias ServiceInfo = |
||||||
|
{ fields : List String |
||||||
|
, tests : List String |
||||||
|
, mod : String } |
||||||
|
|
||||||
|
type alias Info = List |
||||||
|
{ name : String |
||||||
|
, fields : List String |
||||||
|
, tests : List String |
||||||
|
, mod : String } |
||||||
|
|
||||||
|
type Model |
||||||
|
= Failure |
||||||
|
| Loading |
||||||
|
| Success Info |
||||||
|
|
||||||
|
type Msg = GotInfo (Result Http.Error Info) |
||||||
|
|
||||||
|
main = Browser.element |
||||||
|
{ init = init |
||||||
|
, update = update |
||||||
|
, subscriptions = subscriptions |
||||||
|
, view = view } |
||||||
|
|
||||||
|
init : () -> (Model, Cmd Msg) |
||||||
|
init _ = |
||||||
|
( Loading |
||||||
|
, Http.get |
||||||
|
{ url = "https://share.recursor.wf/systemd-services-tests.json" |
||||||
|
, expect = Http.expectJson GotInfo dataDecoder } ) |
||||||
|
|
||||||
|
dataDecoder : Decoder Info |
||||||
|
dataDecoder = map (List.map (\(name, (fields, tests, mod)) -> { name = name, fields = fields, tests = tests, mod = mod })) |
||||||
|
<| keyValuePairs (map3 (\x y z -> (x, y, z)) (field "fields" <| list string) (field "tests" <| list string) (field "module" string)) |
||||||
|
|
||||||
|
update : Msg -> Model -> (Model, Cmd Msg) |
||||||
|
update msg model = |
||||||
|
case msg of |
||||||
|
GotInfo result -> |
||||||
|
case result of |
||||||
|
Ok info -> (Success info, Cmd.none) |
||||||
|
Err _ -> (Failure, Cmd.none) |
||||||
|
|
||||||
|
subscriptions : Model -> Sub Msg |
||||||
|
subscriptions model = Sub.none |
||||||
|
|
||||||
|
-- Render |
||||||
|
|
||||||
|
watchedFields = |
||||||
|
[ "PrivateDevices" |
||||||
|
, "PrivateMounts" |
||||||
|
, "PrivateNetwork" |
||||||
|
, "PrivateTmp" |
||||||
|
, "PrivateUsers" |
||||||
|
, "ProtectControlGroups" |
||||||
|
, "ProtectKernelModules" |
||||||
|
, "ProtectKernelTunables" |
||||||
|
, "ProtectKernelLogs" |
||||||
|
, "ProtectClock" |
||||||
|
, "ProtectHostname" |
||||||
|
, "LockPersonality" |
||||||
|
, "MemoryDenyWriteExecute" |
||||||
|
, "NoNewPrivileges" |
||||||
|
, "RestrictRealtime" |
||||||
|
, "RestrictSUIDSGID" ] |
||||||
|
|
||||||
|
view : Model -> Html Msg |
||||||
|
view model = case model of |
||||||
|
Failure -> text "Unable to load data." |
||||||
|
Loading -> text "Loading..." |
||||||
|
Success info -> renderTable info |
||||||
|
|
||||||
|
headers : Html Msg |
||||||
|
headers = tr [] |
||||||
|
<| [ th [] [ text "source" ], th [] [ text "module" ] ] |
||||||
|
++ List.map (\name -> th [ class "rotate-45" ] [ div [] [ span [] [ text name ] ] ]) watchedFields |
||||||
|
|
||||||
|
renderTable : Info -> Html Msg |
||||||
|
renderTable info = table [ class "services-table", class "table-header-rotated" ] |
||||||
|
[ thead [ class "info-thead" ] [ headers ] |
||||||
|
, tbody [] (List.map renderLine info) ] |
||||||
|
|
||||||
|
renderLine : { name : String, fields : List String, tests : List String, mod : String } -> Html Msg |
||||||
|
renderLine {name, fields, tests, mod} = tr [] |
||||||
|
<| [ th [] [ text mod ], th [] [ text name ] ] |
||||||
|
++ (List.map (\b -> td [class (if b then "cell-good" else "cell-bad")] [text (if b then "✓" else "✗")]) |
||||||
|
<| List.map (\field -> not <| List.member field fields) watchedFields) |
||||||
|
|
@ -0,0 +1,27 @@ |
|||||||
|
{ |
||||||
|
"type": "application", |
||||||
|
"source-directories": [ |
||||||
|
"./" |
||||||
|
], |
||||||
|
"elm-version": "0.19.1", |
||||||
|
"dependencies": { |
||||||
|
"direct": { |
||||||
|
"elm/browser": "1.0.2", |
||||||
|
"elm/core": "1.0.5", |
||||||
|
"elm/html": "1.0.0", |
||||||
|
"elm/http": "2.0.0", |
||||||
|
"elm/json": "1.1.3" |
||||||
|
}, |
||||||
|
"indirect": { |
||||||
|
"elm/bytes": "1.0.8", |
||||||
|
"elm/file": "1.0.5", |
||||||
|
"elm/time": "1.0.0", |
||||||
|
"elm/url": "1.0.0", |
||||||
|
"elm/virtual-dom": "1.0.3" |
||||||
|
} |
||||||
|
}, |
||||||
|
"test-dependencies": { |
||||||
|
"direct": {}, |
||||||
|
"indirect": {} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>Packages info</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="app"></div> |
||||||
|
</body> |
||||||
|
<style> |
||||||
|
.info-thead { |
||||||
|
position: sticky; |
||||||
|
top: 0; |
||||||
|
} |
||||||
|
.cell-good { |
||||||
|
color: green; |
||||||
|
} |
||||||
|
.cell-bad { |
||||||
|
color: red; |
||||||
|
} |
||||||
|
.services-table { |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
.services-table thead { |
||||||
|
background-color: white; |
||||||
|
} |
||||||
|
.services-table thead th { |
||||||
|
vertical-align: bottom; |
||||||
|
} |
||||||
|
.services-table td { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.services-table tbody th { |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
/* Rotated table headers, borrowed from http://jimmybonney.com/articles/column_header_rotation_css */ |
||||||
|
/* Adapted by me, without a calculator */ |
||||||
|
|
||||||
|
.tab-content { |
||||||
|
margin-right: 5em; |
||||||
|
overflow: visible; |
||||||
|
} |
||||||
|
|
||||||
|
td.centered { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.table-header-rotated th.rotate-45 { |
||||||
|
height: 200px; |
||||||
|
width: 40px; |
||||||
|
min-width: 40px; |
||||||
|
max-width: 40px; |
||||||
|
position: relative; |
||||||
|
vertical-align: bottom; |
||||||
|
padding: 0; |
||||||
|
font-size: 100%; |
||||||
|
line-height: 0.9; |
||||||
|
} |
||||||
|
|
||||||
|
.table-header-rotated th.rotate-45 > div { |
||||||
|
position: relative; |
||||||
|
top: 0px; |
||||||
|
left: 100px; |
||||||
|
height: 100%; |
||||||
|
-ms-transform:skew(-45deg,0deg); |
||||||
|
-moz-transform:skew(-45deg,0deg); |
||||||
|
-webkit-transform:skew(-45deg,0deg); |
||||||
|
-o-transform:skew(-45deg,0deg); |
||||||
|
transform:skew(-45deg,0deg); |
||||||
|
overflow: hidden; |
||||||
|
border-left: 1px solid #dddddd; |
||||||
|
z-index: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.table-header-rotated th.rotate-45 span { |
||||||
|
-ms-transform:skew(45deg,0deg) rotate(315deg); |
||||||
|
-moz-transform:skew(45deg,0deg) rotate(315deg); |
||||||
|
-webkit-transform:skew(45deg,0deg) rotate(315deg); |
||||||
|
-o-transform:skew(45deg,0deg) rotate(315deg); |
||||||
|
transform:skew(45deg,0deg) rotate(315deg); |
||||||
|
position: absolute; |
||||||
|
bottom: 85px; left: -107px; display: inline-block; |
||||||
|
width: 254px; text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
</style> |
||||||
|
<script src="/ServicesTable.js"></script> |
||||||
|
<script> |
||||||
|
Elm.ServicesTable.init({ |
||||||
|
node: document.getElementById("app"), |
||||||
|
}); |
||||||
|
</script> |
||||||
|
</html> |
@ -1,11 +1,11 @@ |
|||||||
{ mkDerivation, base, hakyll, lib, pandoc }: |
{ mkDerivation, base, hakyll, hakyll-process, lib, pandoc }: |
||||||
mkDerivation { |
mkDerivation { |
||||||
pname = "ssg"; |
pname = "ssg"; |
||||||
version = "0.1.0.0"; |
version = "0.1.0.0"; |
||||||
src = ./.; |
src = ./.; |
||||||
isLibrary = false; |
isLibrary = false; |
||||||
isExecutable = true; |
isExecutable = true; |
||||||
executableHaskellDepends = [ base hakyll pandoc ]; |
executableHaskellDepends = [ base hakyll hakyll-process pandoc ]; |
||||||
license = "unknown"; |
license = "unknown"; |
||||||
hydraPlatforms = lib.platforms.none; |
hydraPlatforms = lib.platforms.none; |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue