Initial commit
This commit is contained in:
commit
cacc836535
|
@ -0,0 +1,2 @@
|
|||
result
|
||||
dist-newstyle
|
|
@ -0,0 +1,11 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
@ -0,0 +1,12 @@
|
|||
Display Weathernews caster ages in an HTML table or as plain text: if there's no "TERM"
|
||||
environment variable set, HTML output. I'll try to run it as a CGI program.
|
||||
|
||||
Learning Haskell, so the code might not be the best.
|
||||
|
||||
Run ~nix-build~ to build the executable. A "result" directory will be created wiith the
|
||||
executable under it.
|
||||
|
||||
Run ~nix-shell~ to get a subshell with the packges specified in "default.nix". Actual
|
||||
Haskell library dependencies of the executable need to be specified only in the cabal
|
||||
file. Once in the subshell, run ~cabal repl~ to load the executable into ghci and start
|
||||
experimenting.
|
|
@ -0,0 +1 @@
|
|||
<!DOCTYPE html><html><head><title>WNI caster birthdays and ages</title><link rel="stylesheet" href="style.css"></head><body><p>2023-11-23 03:51:45.900476504</p><table><thead><tr><td>名前</td><td>生年月日</td><td>年</td><td>箇月</td><td>日</td></tr></thead><tbody><tr><td>山岸愛梨</td><td>1987-06-09</td><td>36</td><td>5</td><td>14</td></tr><tr><td>江川清音</td><td>1989-12-03</td><td>33</td><td>11</td><td>20</td></tr><tr><td>眞家泉</td><td>1990-09-07</td><td>33</td><td>2</td><td>16</td></tr><tr><td>白井ゆかり</td><td>1991-06-25</td><td>32</td><td>4</td><td>29</td></tr><tr><td>松雪彩花</td><td>1991-09-06</td><td>32</td><td>2</td><td>17</td></tr><tr><td>高安奈緒子</td><td>1992-11-22</td><td>31</td><td>0</td><td>1</td></tr><tr><td>檜山沙耶</td><td>1993-10-27</td><td>30</td><td>0</td><td>27</td></tr><tr><td>高山奈々</td><td>1994-06-17</td><td>29</td><td>5</td><td>6</td></tr><tr><td>内田侑希</td><td>1995-12-08</td><td>27</td><td>11</td><td>15</td></tr><tr><td>駒木結衣</td><td>1996-06-09</td><td>27</td><td>5</td><td>14</td></tr><tr><td>武藤彩芽</td><td>1996-08-31</td><td>27</td><td>2</td><td>23</td></tr><tr><td>魚住茉由</td><td>1998-12-06</td><td>24</td><td>11</td><td>17</td></tr><tr><td>青原桃香</td><td>1999-01-05</td><td>24</td><td>10</td><td>18</td></tr><tr><td>大島璃音</td><td>1999-03-19</td><td>24</td><td>8</td><td>4</td></tr><tr><td>小川千奈</td><td>1999-06-30</td><td>24</td><td>4</td><td>24</td></tr><tr><td>小林李衣奈</td><td>1999-11-17</td><td>24</td><td>0</td><td>6</td></tr><tr><td>戸北美月</td><td>1999-12-29</td><td>23</td><td>10</td><td>25</td></tr><tr><td>岡本結子リサ</td><td>2000-01-30</td><td>23</td><td>9</td><td>24</td></tr></tbody></table></body></html>
|
|
@ -0,0 +1,124 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell --pure -i runghc -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [ json ])"
|
||||
|
||||
-- https://wiki.haskell.org/Getting_the_current_date
|
||||
-- https://hackage.haskell.org/package/time-1.13/docs/Data-Time.html datetime modules overview
|
||||
-- https://hackage.haskell.org/package/time-1.12.2/docs/Data-Time-Clock.html
|
||||
-- https://hackage.haskell.org/package/time-1.12.2/docs/Data-Time-Calendar.html
|
||||
-- https://hackage.haskell.org/package/time-1.12.2/docs/Data-Time-LocalTime.html
|
||||
-- https://mmhaskell.com/monads/reader-writer
|
||||
|
||||
-- https://hackage.haskell.org/package/type-of-html-1.6.2.0/docs/Html.html
|
||||
-- https://github.com/knupfer/type-of-html
|
||||
|
||||
-- Overview of all language extension
|
||||
-- https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/table.html
|
||||
-- {-# LANGUAGE DuplicateRecordFields #-}
|
||||
|
||||
-- super sick extension learned here https://stackoverflow.com/questions/38052553/haskell-record-pattern-matching
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
|
||||
import Data.Time
|
||||
import Data.List
|
||||
import Html
|
||||
import Control.Monad.Reader
|
||||
import System.Environment
|
||||
|
||||
data Caster = Caster
|
||||
{ casterName :: String
|
||||
, casterBday :: Day }
|
||||
deriving (Show)
|
||||
|
||||
data Age = Age
|
||||
{ ageY :: String
|
||||
, ageM :: String
|
||||
, ageD :: String }
|
||||
deriving (Show)
|
||||
|
||||
casters :: [Caster]
|
||||
casters = [ Caster "山岸愛梨" $ YearMonthDay 1987 06 09
|
||||
, Caster "松雪彩花" $ YearMonthDay 1991 09 06
|
||||
, Caster "武藤彩芽" $ YearMonthDay 1996 08 31
|
||||
, Caster "眞家泉" $ YearMonthDay 1990 09 07
|
||||
, Caster "魚住茉由" $ YearMonthDay 1998 12 06
|
||||
, Caster "戸北美月" $ YearMonthDay 1999 12 29
|
||||
, Caster "青原桃香" $ YearMonthDay 1999 01 05
|
||||
, Caster "高山奈々" $ YearMonthDay 1994 06 17
|
||||
, Caster "高安奈緒子" $ YearMonthDay 1992 11 22
|
||||
, Caster "小林李衣奈" $ YearMonthDay 1999 11 17
|
||||
, Caster "大島璃音" $ YearMonthDay 1999 03 19
|
||||
, Caster "檜山沙耶" $ YearMonthDay 1993 10 27
|
||||
, Caster "江川清音" $ YearMonthDay 1989 12 03
|
||||
, Caster "小川千奈" $ YearMonthDay 1999 06 30
|
||||
, Caster "駒木結衣" $ YearMonthDay 1996 06 09
|
||||
, Caster "岡本結子リサ" $ YearMonthDay 2000 01 30
|
||||
, Caster "白井ゆかり" $ YearMonthDay 1991 06 25
|
||||
, Caster "内田侑希" $ YearMonthDay 1995 12 08 ]
|
||||
|
||||
jptz :: TimeZone
|
||||
jptz = TimeZone (9 * 60) False "JST" -- define JST time zone as 9 hours past UTC https://time.is/ja/Japan
|
||||
|
||||
jplocaltime :: IO LocalTime
|
||||
jplocaltime = (utcToLocalTime jptz) <$> getCurrentTime
|
||||
|
||||
dayToTime :: Day -> LocalTime
|
||||
dayToTime day = LocalTime day midnight
|
||||
|
||||
timeSinceBirth :: Reader LocalTime (Day -> Age)
|
||||
timeSinceBirth = do
|
||||
jptime <- ask
|
||||
return (\bday ->
|
||||
let today = localDay jptime
|
||||
monthsAndDays = diffGregorianDurationClip today bday
|
||||
totalMonths = cdMonths monthsAndDays
|
||||
y = div totalMonths 12
|
||||
m = rem totalMonths 12
|
||||
d = cdDays monthsAndDays
|
||||
in Age (show y) (show m) (show d))
|
||||
|
||||
casterAgeInfo :: Reader LocalTime (Caster -> (Caster, Age))
|
||||
casterAgeInfo = do
|
||||
timeSinceBirth' <- timeSinceBirth
|
||||
return (\caster ->
|
||||
let age = timeSinceBirth' $ casterBday caster
|
||||
in (caster,age))
|
||||
|
||||
textline :: (Caster, Age) -> String
|
||||
textline (Caster{..}, Age{..}) =
|
||||
casterName ++ "born " ++ (show casterBday) ++ " " ++
|
||||
ageY ++ " years, " ++ ageM ++ " months, " ++ ageD ++ " days old."
|
||||
|
||||
textoutput :: [(Caster, Age)] -> IO ()
|
||||
textoutput datalist = do
|
||||
jptime <- jplocaltime
|
||||
putStrLn $ "日本での現在時刻 " ++ (show jptime)
|
||||
putStr . unlines $ map textline datalist
|
||||
|
||||
webpage jptime tds =
|
||||
DOCTYPE # Html :>
|
||||
(Head :>
|
||||
(Title :> "WNI caster birthdays and ages" #
|
||||
Link :@ (RelA := "stylesheet" # HrefA := "style.css")) #
|
||||
Body :>
|
||||
(P :> ("日本での現在時刻 " ++ (show jptime)) #
|
||||
Table :>
|
||||
(Thead :>
|
||||
Tr :> (Td :> "名前" # Td :> "生年月日" # Td :> "年" # Td :> "箇月" # Td :> "日") #
|
||||
Tbody :> tds)))
|
||||
|
||||
tablerow (Caster{..}, Age{..}) =
|
||||
Tr :> (Td :> casterName # Td :> (show casterBday) # Td :> ageY # Td :> ageM # Td :> ageD)
|
||||
|
||||
htmloutput :: [(Caster,Age)] -> IO ()
|
||||
htmloutput datalist = do
|
||||
jptime <- jplocaltime
|
||||
putStr . renderString . webpage jptime $ map tablerow datalist
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
console <- lookupEnv "TERM"
|
||||
jptime <- jplocaltime
|
||||
let output = if console /= Nothing then textoutput else htmloutput
|
||||
sortedByBday = sortOn casterBday casters :: [Caster]
|
||||
datalist = map (runReader casterAgeInfo jptime) sortedByBday :: [(Caster,Age)]
|
||||
in output datalist
|
|
@ -0,0 +1,80 @@
|
|||
cabal-version: 3.0
|
||||
-- The cabal-version field refers to the version of the .cabal specification,
|
||||
-- and can be different from the cabal-install (the tool) version and the
|
||||
-- Cabal (the library) version you are using. As such, the Cabal (the library)
|
||||
-- version used must be equal or greater than the version stated in this field.
|
||||
-- Starting from the specification version 2.2, the cabal-version field must be
|
||||
-- the first thing in the cabal file.
|
||||
|
||||
-- Initial package description 'hask' generated by
|
||||
-- 'cabal init'. For further documentation, see:
|
||||
-- http://haskell.org/cabal/users-guide/
|
||||
--
|
||||
-- The name of the package.
|
||||
name: caster-age
|
||||
|
||||
-- The package version.
|
||||
-- See the Haskell package versioning policy (PVP) for standards
|
||||
-- guiding when and how versions should be incremented.
|
||||
-- https://pvp.haskell.org
|
||||
-- PVP summary: +-+------- breaking API changes
|
||||
-- | | +----- non-breaking API additions
|
||||
-- | | | +--- code changes with no API change
|
||||
version: 0.1.0.0
|
||||
|
||||
-- A short (one-line) description of the package.
|
||||
-- synopsis:
|
||||
|
||||
-- A longer description of the package.
|
||||
-- description:
|
||||
|
||||
-- The license under which the package is released.
|
||||
license: GPL-3.0-only
|
||||
|
||||
-- The file containing the license text.
|
||||
license-file: LICENSE
|
||||
|
||||
-- The package author(s).
|
||||
author: pta
|
||||
|
||||
-- An email address to which users can send suggestions, bug reports, and patches.
|
||||
maintainer: in your walls
|
||||
|
||||
-- A copyright notice.
|
||||
-- copyright:
|
||||
category: Database
|
||||
build-type: Simple
|
||||
|
||||
-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README.
|
||||
extra-doc-files: CHANGELOG.md
|
||||
|
||||
-- Extra source files to be distributed with the package, such as examples, or a tutorial module.
|
||||
-- extra-source-files:
|
||||
|
||||
common warnings
|
||||
ghc-options: -Wall
|
||||
|
||||
executable caster-age
|
||||
-- Import common warning flags.
|
||||
import: warnings
|
||||
|
||||
-- .hs or .lhs file containing the Main module.
|
||||
main-is: Main.hs
|
||||
|
||||
-- Modules included in this executable, other than Main.
|
||||
-- other-modules:
|
||||
|
||||
-- LANGUAGE extensions used by modules in this package.
|
||||
-- other-extensions:
|
||||
|
||||
-- Other library packages from which modules are imported.
|
||||
build-depends: base ^>=4.17.2.0,
|
||||
type-of-html,
|
||||
time,
|
||||
mtl
|
||||
|
||||
-- Directories containing source files.
|
||||
hs-source-dirs: app
|
||||
|
||||
-- Base language which the package is written in.
|
||||
default-language: Haskell2010
|
|
@ -0,0 +1,11 @@
|
|||
let
|
||||
pkgs = import <nixpkgs> { }; # pin the channel to ensure reproducibility!
|
||||
in
|
||||
pkgs.haskellPackages.developPackage {
|
||||
root = ./.;
|
||||
modifier = drv:
|
||||
pkgs.haskell.lib.addBuildTools drv ((with pkgs.haskellPackages;
|
||||
[ cabal-install
|
||||
ghcid
|
||||
]) ++ (with pkgs; [sqlite]));
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Styling_tables */
|
||||
|
||||
/* spacing */
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
text-align: end;
|
||||
/* border: 3px solid purple; */
|
||||
}
|
||||
|
||||
thead {
|
||||
background-color: #ccf3ff;
|
||||
}
|
||||
|
||||
thead th:nth-child(1) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
thead th:nth-child(2) {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
thead th:nth-child(3) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
thead th:nth-child(4) {
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 1px 16px 1px 0px;
|
||||
}
|
||||
|
||||
/* zebra striping */
|
||||
|
||||
/* tbody tr:nth-child(odd) { */
|
||||
/* background-color: #dadada; */
|
||||
/* } */
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
/* table { */
|
||||
/* background-color: #ff33cc; */
|
||||
/* } */
|
Loading…
Reference in New Issue