-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathPeople.hs
More file actions
197 lines (163 loc) · 5.51 KB
/
People.hs
File metadata and controls
197 lines (163 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
{-# LANGUAGE DeriveGeneric, OverloadedStrings #-}
module People where
import Prelude hiding (div, span)
import GHC.Generics
import Data.Yaml
import Data.Functor
import Data.List hiding (span)
import Data.Maybe
import qualified Data.ByteString as BS
import Control.Monad
import System.Directory
import System.FilePath
import Html
import Translate
type Markdown = String
data Status = Academic | PhDStudent | PhDStaff | Research | PhDFinished | Alum
deriving (Show, Eq, Generic)
instance FromJSON Status where
parseJSON (String "academic") = pure Academic
parseJSON (String "phd-student") = pure PhDStudent
parseJSON (String "research") = pure Research
parseJSON (String "phd-finished") = pure PhDFinished
parseJSON (String "phd-staff") = pure PhDStaff
parseJSON (String "alum") = pure Alum
parseJSON _ = fail "invalid status"
data LinkRelationship
= HomePage
| Pure
| Thesis
| Staff
deriving (Show, Eq, Generic)
instance FromJSON LinkRelationship where
parseJSON (String "homepage") = pure HomePage
parseJSON (String "staff") = pure Staff
parseJSON (String "pure") = pure Pure
parseJSON (String "thesis") = pure Thesis
parseJSON _ = fail "invalid link type"
data Link =
Link { href :: String
, rel :: LinkRelationship
-- , linkTitle :: Maybe String
}
deriving (Show, Eq, Generic)
instance FromJSON Link
data Person = Person
{ firstname :: String
, lastname :: String
, ident :: String
, pronouns :: Maybe String
, title :: Maybe String
, status :: Status
, picture :: Maybe String
, email :: Maybe String
, webpage :: Maybe String
, links :: Maybe [Link]
, description :: Markdown
, phdTopics :: Maybe [Markdown] -- Only relevant for status == Academic
} deriving (Show, Eq, Generic)
name :: Person -> String
name p = firstname p ++ " " ++ lastname p
instance FromJSON Person
hasStatus :: Status -> Person -> Bool
hasStatus s p = (==) s (status p)
currentMember :: Person -> Bool
currentMember p = case status p of
Academic -> True
Research -> True
PhDStaff -> True
PhDStudent -> True
PhDFinished -> False
Alum -> False
data MSP
= MSP
{ preamble :: Markdown
, people :: [Person]
} deriving (Show,Eq,Generic)
instance FromJSON MSP
data MSPGrouped
= MSPGrouped
{
academic :: [Person]
, research :: [Person]
, student :: [Person]
, alumni :: [Person]
}
------------------------------------------------------------------------------
linkToHTML :: Link -> HTML
linkToHTML link = case rel link of
HomePage -> anchor (href link) "homepage"
Staff -> anchor ("http://www.strath.ac.uk/staff/" ++ href link) "Staff page"
Pure -> anchor ("https://pureportal.strath.ac.uk/en/persons/" ++ href link) "Staff page (pure)"
Thesis -> anchor (href link) "PhD Thesis"
statusToHTML :: Status -> HTML
statusToHTML Academic = "Academic staff"
statusToHTML Research = "Research staff"
statusToHTML PhDStudent = "PhD student"
statusToHTML PhDStaff = "PhD Student & Teaching Staff"
statusToHTML PhDFinished = "Alumnus (PhD)"
statusToHTML Alum = "Alumus"
personToHTML :: Person -> IO HTML
personToHTML person = do
let nom = maybe "" (++" ") (title person) ++ name person
let prnouns = maybe "" (\ x -> " " ++ span "grayish" ("(" ++ x ++ ")")) (pronouns person)
let links = intersperse " or email " $ catMaybes [homepage person, maillink person]
desc <- translateMarkdown (description person ++ concatStop links)
image <- case currentMember person of
True -> do
cand <- imageFromIdent (ident person)
pure (Just (maybe "images/people/placeholder.jpg" id cand))
False -> pure Nothing
let body = concat [strong nom, prnouns, desc]
pure $ div "person" $ concat $ catMaybes
[ (div "person-image" . img (Just "border-radius: 20%; height: 100px;") (name person)) <$> image
, pure (div "person-description" body)
]
where
maillink :: Person -> Maybe HTML
maillink person | hasStatus Academic person
= fmap emailToHTML (email person)
maillink person | otherwise = Nothing
homepage :: Person -> Maybe HTML
homepage person = fmap (\ w -> "See " ++ anchor w (firstname person ++ "'s webpage")) (webpage person)
concatStop :: [String] -> String
concatStop [] = ""
concatStop xs = concat $ xs ++ ["."]
imageFromIdent :: String -> IO (Maybe String)
imageFromIdent ident = do
images <- listDirectory "images/people/"
case [ image | image <- images, dropExtensions image == ident] of
(path:_) -> pure (Just $ "images/people/" </> path)
_ -> do
putStrLn $ "Warning: did not find an image for '" ++ ident ++ "'"
pure Nothing
peopleToHTML :: HTML -> [Person] -> IO HTML
peopleToHTML _ [] = pure ""
peopleToHTML title (p:ps) = do
content <- traverse personToHTML (p:ps)
pure
$ unlines
[ h3 title
, div "people" $ unlines content
]
groupMSP :: [Person] -> MSPGrouped
groupMSP
= foldl bucket (MSPGrouped [] [] [] [])
where
bucket :: MSPGrouped -> Person -> MSPGrouped
bucket g p =
case status p of
Academic -> g { academic = academic g ++ [p] }
PhDStudent -> g { student = student g ++ [p] }
PhDStaff -> g { student = student g ++ [p] }
Research -> g { research = research g ++ [p] }
PhDFinished -> g { alumni = alumni g ++ [p] }
Alum -> g { alumni = alumni g ++ [p] }
readPeopleFile :: FilePath -> IO MSP
readPeopleFile file = do
f <- BS.readFile file
case decodeEither' f of
Left err ->
error (show err)
Right input -> do
pure input