[Fencommits] fenserve: refactor (changes file format)
Benja Fallenstein
benja.fallenstein at gmail.com
Fri Apr 27 21:02:48 EEST 2007
Fri Apr 27 21:02:40 EEST 2007 Benja Fallenstein <benja.fallenstein at gmail.com>
* refactor (changes file format)
diff -rN -u old-fenserve/notetaker/Main.hs new-fenserve/notetaker/Main.hs
--- old-fenserve/notetaker/Main.hs 2007-04-27 21:02:48.000000000 +0300
+++ new-fenserve/notetaker/Main.hs 2007-04-27 21:02:48.000000000 +0300
@@ -1,21 +1,24 @@
{-# OPTIONS_GHC -fglasgow-exts #-}
-import HAppS
+import HAppS hiding (Body)
import Control.Monad.State
import Data.Generics (Typeable)
import Data.Binary hiding (get,put)
import Data.Char
-import Data.List (isPrefixOf)
+import Data.List (intersperse, isPrefixOf)
import Data.Maybe (fromMaybe)
import Text.Printf
import System.Time
+type Path = [Int]
+data Body = Body String | Add Path String | Edit Path String | Delete Path
+ deriving (Eq,Ord,Read,Show,Typeable)
data Line = Line { lineTime :: EpochTime, lineNick :: String,
- lineBody :: String } deriving (Eq,Ord,Read,Show,Typeable)
+ lineBody :: Body } deriving (Eq,Ord,Read,Show,Typeable)
instance Binary Line where
-data Note = Note String [Note] deriving (Eq,Ord,Read,Show,Typeable)
+data Note = Note String [Note] deriving (Eq,Ord,Read,Show)
form nick = "<form id='myform' action='/log' method='post'>\
\ Nick: <input name='nick' type='text' size=8 \
@@ -37,28 +40,25 @@
renderNotes notes = "<ol>" ++ concatMap renderNote notes ++ "</ol>" where
renderNote (Note title children) = "<li>" ++ title ++ renderNotes children
-execute (Line time nick line0) =
- if ":del " `isPrefixOf` line0
- then delete (map (subtract 1) $ read $ drop 5 line0)
- else if ":add " `isPrefixOf` line0
- then let (path, line1) = head $ reads (drop 5 line0)
- in addToPath (map (subtract 1) path) (dropWhile isSpace line1)
- else if ":edit " `isPrefixOf` line0
- then let (path, line1) = head $ reads (drop 6 line0)
- in edit (map (subtract 1) path) (dropWhile isSpace line1)
- else id where
-
- replace i notes' notes = take i notes ++ notes' ++ drop (i+1) notes
-
- delete [i] (Note t cs) = Note t (replace i [] cs)
- delete (i:is) (Note t cs) = Note t (replace i [delete is $ cs !! i] cs)
-
- addToPath [] line (Note t cs) = Note t (cs ++ [Note line []])
- addToPath (i:is) line (Note t cs) =
- Note t (replace i [addToPath is line $ cs !! i] cs)
-
- edit [] line (Note _ cs) = Note line cs
- edit (i:is) line (Note t cs) = Note t (replace i [edit is line $ cs !! i] cs)
+readPath s n f = f (map (subtract 1) path) (dropWhile isSpace line) where
+ ((path, line):_) = reads (drop n s)
+
+readBody :: String -> Body
+readBody s | ":add " `isPrefixOf` s = readPath s 5 $ \p l -> Add p l
+ | ":edit " `isPrefixOf` s = readPath s 6 $ \p l -> Edit p l
+ | ":del " `isPrefixOf` s = readPath s 5 $ \p "" -> Delete p
+ | otherwise = Body s
+
+execute (Line _ _ (Body _)) = id
+execute (Line _ _ body) =
+ case body of Add p l -> on p $ \(Note t cs) -> [Note t (cs++[Note l []])]
+ Edit p l -> on p $ \(Note _ cs) -> [Note l cs]
+ Delete p -> on p $ \_ -> []
+
+ where on is f note = head $ on' is f note
+ on' [] f note = f note
+ on' (i:is) f (Note t cs) =
+ [Note t (take i cs ++ on' is f (cs !! i) ++ drop (i+1) cs)]
getNick m = case lookM m "nick" of Nothing -> "(anon)"; Just "" -> "(anon)"
Just x -> x
@@ -73,8 +73,19 @@
lines <- get
respond $ form nick
++ "Views: <a href='/?nick="++nick++"'>main</a> | <b>log</b><p>"
- ++ flip concatMap lines (\(Line t n l) ->
- printf "%s <<b>%s</b>> %s<br>" (renderTime t) n l :: String)
+ ++ flip concatMap lines (\(Line time nick body) ->
+ renderTime time ++ " " ++ renderBody nick body ++ "<br>")
+
+renderBody :: String -> Body -> String
+renderBody nick (Body s) = printf "<<b>%s</b>> %s" nick s
+renderBody nick body = printf "<b>%s</b> %s" nick (msg body) where
+ msg :: Body -> String
+ msg (Add [] l) = printf "<i>adds:</i> %s" l
+ msg (Add p l) = printf "<i>adds to %s:</i> %s" (renderPath p) l
+ msg (Edit p l) = printf "<i>edits %s:</i> %s" (renderPath p) l
+ msg (Delete p) = printf "<i>deletes %s.</i>" (renderPath p)
+
+ renderPath = concat . intersperse "." . map (show . (+1))
renderTime :: EpochTime -> String
renderTime t0 = printf "%02u:%02u" (ctHour t) (ctMin t)
@@ -85,7 +96,8 @@
, h [""] GET $ ok $ \() nick -> page nick
, h ["log"] POST $ ok $ \() (nick,line) -> do
time <- getTime
- modify (++[Line time nick line]); renderLog nick
+ modify (++[Line time nick $ readBody line])
+ renderLog nick
, h () POST $ ok $ \() () -> respond "Huh."
]
More information about the Fencommits
mailing list