does it work?

This commit is contained in:
Dennis Frieberg 2024-10-09 08:14:47 +02:00
parent 7ec9a8f10e
commit 9b949230dd
No known key found for this signature in database
GPG key ID: 7C58AFED036072C5
28 changed files with 188 additions and 114 deletions

View file

@ -39,6 +39,7 @@ library
Handler.Common
Handler.Home
Handler.Station
Handler.Ad
Import
Import.NoFoundation
Model
@ -72,6 +73,7 @@ library
, persistent >=2.9 && <2.15
, persistent-sqlite >=2.9 && <2.14
, persistent-template >=2.5 && <2.14
, random
, safe
, shakespeare >=2.0 && <2.2
, template-haskell

BIN
ads/image0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

BIN
ads/image1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
ads/image2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
ads/image3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
ads/image4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -15,6 +15,8 @@
-- stationName/roundNumber
/station/#Text/#Int StationRoundR GET POST
/ad/ AdR GET
-- /comments CommentR POST

View file

@ -41,3 +41,5 @@ copyright: Insert copyright statement here
stations:
- station-id: "test"
station-name: "Test"
ad-files: "ads/"

View file

@ -5,11 +5,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1719994518,
"narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
"lastModified": 1727826117,
"narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
"rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1",
"type": "github"
},
"original": {
@ -20,11 +20,11 @@
},
"haskell-flake": {
"locked": {
"lastModified": 1720977934,
"narHash": "sha256-k9kwz2lpUqafRUpuCMgkv4AWtHEoJPCds1ZPRkyW2XE=",
"lastModified": 1728227251,
"narHash": "sha256-JLDhMFyGyFe0QJAbCuSxB7/kjUCA7uUAMa6BFRORwXk=",
"owner": "srid",
"repo": "haskell-flake",
"rev": "cd449f1c04175efdf5b553302d22916640090066",
"rev": "9cbfbfc38f1fbf9a0f471795c84780211875fd45",
"type": "github"
},
"original": {
@ -35,11 +35,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1721466660,
"narHash": "sha256-pFSxgSZqZ3h+5Du0KvEL1ccDZBwu4zvOil1zzrPNb3c=",
"lastModified": 1728279793,
"narHash": "sha256-W3D5YpNrUVTFPVU4jiEiboaaUDShaiH5fRl9aJLqUnU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "6e14bbce7bea6c4efd7adfa88a40dac750d80100",
"rev": "f85a2d005e83542784a755ca8da112f4f65c4aa4",
"type": "github"
},
"original": {
@ -51,14 +51,14 @@
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1719876945,
"narHash": "sha256-Fm2rDDs86sHy0/1jxTOKB1118Q0O3Uc7EC0iXvXKpbI=",
"lastModified": 1727825735,
"narHash": "sha256-0xHYkMkeLVQAMa7gvkddbPqpxph+hDzdu1XdGPJR+Os=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
"url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
"url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz"
}
},
"root": {

View file

@ -6,6 +6,9 @@
};
outputs = inputs@{ self, nixpkgs, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
flake = {
nixosModules.OwOpointTracker = { import ./module.nix self
};
systems = nixpkgs.lib.systems.flakeExposed;
imports = [ inputs.haskell-flake.flakeModule ];

89
module.nix Normal file
View file

@ -0,0 +1,89 @@
self: {config, pkgs, lib ...}:
with lib;
let
cfg = config.services.owOPointTracker;
format = pkgs.formats.yaml {};
configFile = format.generate "settings.yml" cfg.config
databaseOptionType = types.submodule {
options = {
database = mkOption {
default = "_env:YESOD_SQLITE_DATABASE:OwOpointTracker.sqlite3";
type = types.str;
};
poolsize = mkOption {
default = "_env:YESOD_SQLITE_POOLSIZE:10";
type = types.str;
};
};
};
stationType = types.submodule {
options = {
station-id = mkOption {
default = "Station";
type = types.str;
};
station-name = mkOption {
types = types.str;
};
};
};
{
imports = [];
options.services.owOPointTracker = {
enable = mkEnableOption "OwOPointTracker";
config = {
static-dir = mkOption {
type = types.path;
};
host = mkOption {
type = types.str;
default = "_env:YESOD_HOST:*4";
ad-files = mkOption {
type = types.path;
};
port = mkOption {
default = "_env:YESOD_PORT:3000";
type = types.str;
};
ip-from-header = mkOption {
default = "_env:YESOD_IP_FROM_HEADER:false";
type = types.str;
};
database = {
type = databaseOptionType;
};
copyright = mkOption {
default = "copyright for this mess?";
type = types.str;
};
station = mkOption {
type = types.listOf stationType;
};
};
};
config = mkIf cfg.enable {
users.users.owopoint = {
isSystemUser = true;
group = "owopoint";
createHome = true;
home = "/var/owopoint";
};
users.groups = {
owopoint = {};
};
systemd.services.owOPointTracker = {
wantedBy = ["multi-user.target"];
after = ["network.target"];
serviceConfig = {
ExecStart = "${self.packages.${pkgs.system}.default} ${configFile}";
Restart = always;
User = "owopoint";
Group = "owopoint";
};
};
};
}

View file

@ -43,6 +43,7 @@ import System.Log.FastLogger (defaultBufSize, newStdoutLoggerSet,
import Handler.Common
import Handler.Home
import Handler.Station
import Handler.Ad
-- This line actually creates our YesodDispatch instance. It is the second half
-- of the call to mkYesodData which occurs in Foundation.hs. Please see the

View file

@ -146,8 +146,10 @@ instance Yesod App where
-- value passed to hamletToRepHtml cannot be a widget, this allows
-- you to use normal widget features in default-layout.
-- randomAddNumber <- liftIO $ getStdRandom (randomR (0,4))
pc <- widgetToPageContent $ do
addStylesheet $ StaticR css_bootstrap_css
-- addStylesheet $ StaticR css_bootstrap_css
-- ^ generated from @Settings/StaticFiles.hs@
$(widgetFile "default-layout")
withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")

15
src/Handler/Ad.hs Normal file
View file

@ -0,0 +1,15 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
module Handler.Ad where
import Import
getAdR :: Handler Html
getAdR = do
basePath <- getsYesod (appAdFilePath . appSettings)
number <- applyAtomicGen (randomR (0 :: Int ,4)) globalStdGen
sendFile typePng $ basePath <> "image" <> show number <> ".png"

View file

@ -19,7 +19,8 @@ checkStation stationIdentifier = do
Nothing -> notFound
Just m -> return m
repsertBy :: (MonadIO m, PersistUniqueRead backend, PersistRecordBackend record backend, AtLeastOneUniqueKey record, SafeToInsert record) => record -> ReaderT backend m ()
-- TODO works without the type annotation, but I don't know why this one is wrong. No time to find out now
-- repsertBy :: (MonadIO m, PersistUniqueRead backend, PersistRecordBackend record backend, AtLeastOneUniqueKey record, SafeToInsert record) => record -> ReaderT backend m ()
repsertBy val = do
valM <- getByValue val
case valM of

View file

@ -10,3 +10,5 @@ import Settings.StaticFiles as Import
import Yesod.Auth as Import
import Yesod.Core.Types as Import (loggerSet)
import Yesod.Default.Config2 as Import
import System.Random as Import
import System.Random.Stateful as Import

View file

@ -71,6 +71,7 @@ data AppSettings = AppSettings
-- ^ Copyright text to appear in the footer of the page
, appStations :: Map Text Text
, appAdFilePath :: String
}
instance FromJSON AppSettings where
@ -98,6 +99,7 @@ instance FromJSON AppSettings where
appCopyright <- o .: "copyright"
appStations <- M.fromList . map (\x -> (stationId x, stationName x)) <$> o .: "stations"
appAdFilePath <- o .: "ad-files"
return AppSettings {..}

3
static/css/test.css Normal file
View file

@ -0,0 +1,3 @@
.blubb {
border-width: 300px
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

View file

@ -1,16 +1,6 @@
<!-- Page Contents -->
$if (Just HomeR == mcurrentRoute)
^{widget}
$else
<div .container>
<div .row>
<div .col-md-12>
^{widget}
<!-- Footer -->
<footer .footer>
<div .container>
<p .text-muted>
#{appCopyright $ appSettings master}
<div .container>
<div .ad>
<img src=@{AdR}>
^{widget}

View file

@ -1,28 +1,11 @@
.masthead,
.navbar {
background-color: rgb(27, 28, 29);
body {
font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
}
.navbar-default .navbar-nav > .active > a {
background-color: transparent;
border-bottom: 2px solid white;
}
.navbar-nav {
padding-bottom: 1em;
}
.masthead {
margin-top: -21px;
color: white;
text-align: center;
min-height: 500px;
}
.masthead .header {
max-width: 700px;
margin: 0 auto;
font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
}
.masthead h1.header {
@ -38,36 +21,15 @@
font-weight: normal;
}
.masthead .btn {
margin: 1em 0;
aside,
.ad {
width: 25%;
padding-left: 15px;
margin-left: 15px;
float: right;
}
/* Common styles for all types */
.bs-callout {
padding: 20px;
margin: 20px 0;
border: 1px solid #eee;
border-left-width: 5px;
border-radius: 3px;
}
.bs-callout p:last-child {
margin-bottom: 0;
}
.bs-callout-info {
border-left-color: #1b809e;
}
/* Space things out */
.bs-docs-section {
margin-bottom: 60px;
}
.bs-docs-section:last-child {
margin-bottom: 0;
}
#message {
margin-bottom: 40px;
img {
max-width: 100%;
max-height: 100%;
}

View file

@ -1,27 +1,10 @@
<div .masthead>
<div .container>
<div .row>
<h1 .header>
OwO Geländespiel
<h1 .header>
OWO Geländespiel
<div .container>
<!-- Starting
================================================== -->
<div .bs-docs-section>
<div .row>
<div .col-lg-12>
<div .page-header>
<h1 #Tutors>Tutors
#{tutorP}
<div .points .tutor>
<h1 #Tutors>Tutoren: #{tutorP}
<hr>
<!-- Forms
================================================== -->
<div .bs-docs-section>
<div .row>
<div .col-lg-12>
<div .page-header>
<h1 #Ersties>Ersties
#{erstieP}
<div .points .erstie>
<h1 #Ersties>Ersties: #{erstieP}

View file

@ -2,3 +2,19 @@ li {
line-height: 2em;
font-size: 16px
}
.points {
border-radius: 25px;
font-weight: bold;
margin: auto;
max-width: 50%;
display: flex;
justify-content: center;
align-items: center;
margin-top: 30px;
}
.tutor {
background-color: #f68afc;
}
.erstie {
background-color: #00FF00;
}

View file

@ -1,14 +1,9 @@
<div .masthead>
<div .container>
<div .row>
<h1 .header>
OwO Geländespiel Station #{station} Round #{roundNumber}
<div .container>
<div .bs-docs-section>
<div .row>
<div .col-lg-12>
<div .page-header>
<div .form>
<form method=post action=@{StationRoundR stationIdentifier roundNumber} enctype=#{roundFormEnctype}>
^{roundFormWidget}
<button> Submit

5
templates/round.lucious Normal file
View file

@ -0,0 +1,5 @@
.form {
display: flex;
justify-content: center;
align-items: center;
}

View file

@ -1,14 +1,8 @@
<div .masthead>
<div .container>
<div .row>
<h1 .header>
OwO Geländespiel Station #{station}
<div .container>
<div .bs-docs-section>
<div .row>
<div .col-lg-12>
<div .page-header>
<div .container .form>
<ul>
$forall round <- rounds
<li>

View file

@ -0,0 +1,5 @@
.form {
display: flex;
justify-content: center;
align-items: center;
}