By | Chris Done |
At | 2013-03-01 |
Title | Fix warnings. |
Description |
Edit file src/Hpaste/Controller.hs 33188 → 33188
30 30 import Network.URI
31 31 import Data.Text.Lazy (Text,toStrict)
32 32 import Database.PostgreSQL.Base (withPoolConnection)
33 33 import Database.PostgreSQL.Simple (Pool)
34 34 import Safe (readMay)
- 35 import Snap.Core
+ 35 import Snap.Core
36 36 import Text.Blaze (Html)
37 37 import Text.Blaze.Renderer.Text (renderHtml)
38 38 39 39 -- | Run a controller handler.
40 40 runHandler :: Config -> Pool -> Cache -> Chan Text -> Controller () -> Snap ()
41 41 runHandler conf pool cache anns ctrl = do
42 42 withPoolConnection pool $ \conn -> do
43 43 let state = ControllerState conf conn cache anns
44 44 -- Default to HTML, can be overridden.
45 45 modifyResponse $ setContentType "text/html"
- 46 runReaderT (runController ctrl) state
+ 46 runReaderT (runController ctrl) state
47 47 48 48 -- | Strictly renders HTML to Text before outputting it via Snap.
49 49 -- This ensures that any lazy exceptions are caught by the Snap
50 50 -- handler.
51 51 output :: Html -> Controller ()
… … … … 88 88 -- | Get pagination data.
89 89 getPagination :: Controller Pagination
90 90 getPagination = do
91 91 p <- getInteger "page" 1
92 92 limit <- getInteger "limit" 35
- 93 i <- fmap rqURI getRequest
94 93 uri <- getMyURI
95 94 return Pagination { pnPage = max 1 p
96 95 , pnLimit = max 1 (min 100 limit)
97 96 , pnURI = uri
98 97 , pnResults = 0
… … … … Edit file src/Hpaste/View/Browse.hs 33188 → 33188
10 10 11 11 import Hpaste.Types
12 12 import Hpaste.View.Html
13 13 import Hpaste.View.Layout
14 14 import Hpaste.View.Paste (pasteLink)
- 15 import Hpaste.Model.Paste (validNick)
+ 15 16 16 17 17 import Control.Monad
18 18 import Data.Maybe
19 19 import Data.Time.Show (showDateTime)
20 20 import Prelude hiding ((++))
… … … … Edit file src/Hpaste/View/Home.hs 33188 → 33188
10 10 11 11 import Hpaste.Types
12 12 import Hpaste.View.Html
13 13 import Hpaste.View.Layout
14 14 import Hpaste.View.Paste (pasteLink)
- 15 import Hpaste.Model.Paste (validNick)
+ 15 16 16 17 17 import Data.Text (Text)
18 18 import Data.Time.Show (showDateTime)
19 19 import Prelude hiding ((++))
20 20 import Text.Blaze.Html5 as H hiding (map)
… … … … 62 62 td $ showLanguage languages pasteLanguage
63 63 td $ showChannel channels pasteChannel
64 64 authorUri author = updateUrlParam "author" author
65 65 $ updateUrlParam "page" "0"
66 66 $ uri { uriPath = "/browse" }
- 67 + 67 68 68 -- | Browse link.
69 69 browse :: Html
70 70 browse = href ("/browse" :: Text) ("Browse all pastes" :: Text)
… … … … Edit file src/Hpaste/View/Html.hs 33188 → 33188
24 24 25 25 import Control.Arrow ((&&&))
26 26 import Control.Monad (when)
27 27 import Data.Maybe (fromMaybe)
28 28 import Data.Monoid.Operator ((++))
- 29 import Data.Text (pack)
+ 29 30 30 import Data.Text.Lazy (Text)
31 31 import qualified Data.Text.Lazy as T
32 32 import Network.URI.Params
33 33 import Prelude hiding ((++))
34 34 import Text.Blaze.Html5 as H hiding (map,nav)
… … … … 108 108 paginate :: Pagination -> Html -> Html
109 109 paginate pn inner = do
110 110 nav pn True
111 111 inner
112 112 nav pn False
- 113 + 113 114 114 -- | Show a pagination navigation, with results count, if requested.
115 115 nav :: Pagination -> Bool -> Html
116 116 nav pn@Pagination{..} showTotal = do
117 117 H.div ! aClass "pagination" $ do
118 118 H.div ! aClass "inner" $ do
… … … … 135 135 a ! hrefURI uri $ toHtml caption
136 136 137 137 where uri = updateUrlParam "page"
138 138 (show (pnPage + change))
139 139 pnURI
- 140 … … … … Edit file src/Hpaste/View/Layout.hs 33188 → 33188
- 1 {-# OPTIONS -Wall #-}
+ 1 {-# OPTIONS -Wall -fno-warn-unused-do-bind #-}
2 2 {-# LANGUAGE OverloadedStrings #-}
3 3 {-# LANGUAGE RecordWildCards #-}
4 4 5 5 -- | Page layout.
6 6 … … … … 42 42 \t/javascript'; ga.async = true; ga.src = ('https:' \
43 43 \== document.location.protocol ? 'https://ssl' : \
44 44 \'http://www') + '.google-analytics.com/ga.js'; var\
45 45 \ s = document.getElementsByTagName('script')[0]; \
46 46 \s.parentNode.insertBefore(ga, s);})(); </script>"
- 47 + 47 48 48 where js s = script ! A.type_ "text/javascript"
49 49 ! A.src ("/js/" ++ s) $
50 50 return ()
51 51 52 52 -- | Show the hpaste logo.
… … … … Edit file src/Hpaste/View/Paste.hs 33188 → 33188
9 9 ,page
10 10 ,pasteLink
11 11 ,pasteRawLink)
12 12 where
13 13 - 14 import Hpaste.Model.Irclogs (showIrcDateTime)
+ 14 15 15 import Hpaste.Types
16 16 import Hpaste.View.Highlight (highlightPaste)
17 17 import Hpaste.View.Hlint (viewHints)
18 18 import Hpaste.View.Html
19 19 import Hpaste.View.Layout
20 20 - 21 import Control.Applicative
+ 21 import Control.Applicative
22 22 import Control.Arrow ((&&&))
- 23 import Control.Monad
+ 23 import Control.Monad
24 24 import Data.ByteString.UTF8 (toString)
25 25 import Data.List (find,nub)
26 26 import qualified Data.Map as M
27 27 import Data.Maybe
28 28 import Data.Monoid.Operator ((++))
29 29 import Data.Text (Text,pack)
30 30 import qualified Data.Text as T
31 31 import Data.Text.Lazy (fromStrict)
32 32 import Data.Time.Show (showDateTime)
33 33 import Data.Traversable hiding (forM)
- 34 import Numeric
+ 34 35 35 import Prelude hiding ((++))
36 36 import Safe (readMay)
37 37 import Text.Blaze.Html5 as H hiding (map)
38 38 import qualified Text.Blaze.Html5.Attributes as A
39 39 import Text.Blaze.Html5.Extra
… … … … 54 54 ppChans
55 55 ppLangs
56 56 (zip ppAnnotations ppAnnotationHints)
57 57 , pageName = "paste"
58 58 }
- 59 + 59 60 60 -- | A formlet for paste submission / annotateing.
61 61 pasteFormlet :: PasteFormlet -> (Formlet PasteSubmit,Html)
62 62 pasteFormlet pf@PasteFormlet{..} =
63 63 let form = postForm ! A.action (toValue action) $ do
64 64 when pfSubmitted $
… … … … 66 66 H.div ! aClass "errors" $
67 67 mapM_ (p . toHtml) pfErrors
68 68 formletHtml (pasteSubmit pf) pfParams
69 69 submitInput "submit" "Submit"
70 70 in (pasteSubmit pf,form)
- 71 + 71 72 72 where action = case pfAnnotatePaste of
73 73 Just Paste{..} -> "/annotate/" ++ show (fromMaybe pasteId pasteParent)
74 74 where pasteParent = case pasteType of
75 75 AnnotationOf pid -> Just pid
76 76 _ -> Nothing
… … … … 101 101 where defaulting def = fmap swap where
102 102 swap "" = def
103 103 swap x = x
104 104 channels = options channelName channelName pfChannels
105 105 languages = options languageName languageTitle pfLanguages
- 106 + 106 107 107 lookupLang slug = findOption ((==slug).languageName) pfLanguages languageId
108 108 lookupChan slug = findOption ((==slug).channelName) pfChannels channelId
- 109 + 109 110 110 defChan = maybe (fromMaybe "" (annotateChan <|> editChan)
111 111 ,fromMaybe "haskell" (annotateLanguage <|> editLanguage))
112 112 (channelName &&& trim.channelName)
113 113 (pfDefChan >>= findChan)
114 114 findChan name = find ((==name).trim.channelName) pfChannels
115 115 trim = T.dropWhile (=='#')
- 116 - 117 annotateContent = pastePaste <$> pfAnnotatePaste
+ 116 118 117 annotateTitle = ((++ " (annotation)") . pasteTitle) <$> pfAnnotatePaste
119 118 annotateLanguage = join (fmap pasteLanguage pfAnnotatePaste) >>= findLangById
120 119 annotateChan = join (fmap pasteChannel pfAnnotatePaste) >>= findChanById
- 121 - 122 editContent = pastePaste <$> pfEditPaste
+ 120 123 121 editTitle = Nothing
124 122 editLanguage = join (fmap pasteLanguage pfEditPaste) >>= findLangById
125 123 editChan = join (fmap pasteChannel pfEditPaste) >>= findChanById
126 124 127 125 findChanById id = channelName <$> find ((==id).channelId) pfChannels
… … … … 148 146 149 147 -- | List the details of the page in a dark section.
150 148 pasteDetails :: [Paste] -> [Paste] -> [Channel] -> [Language] -> Paste -> Html
151 149 pasteDetails revisions annotations chans langs paste =
152 150 darkNoTitleSection $ do
- 153 pasteNav langs annotations paste
+ 151 pasteNav annotations paste
154 152 h2 $ toHtml $ fromStrict (pasteTitle paste)
155 153 ul ! aClass "paste-specs" $ do
156 154 detail "Paste" $ do
157 155 pasteLink paste $ "#" ++ show (pasteId paste)
158 156 " "
… … … … 186 184 AnnotationOf pid -> do "(an annotation of "; pidLink pid; ")"
187 185 RevisionOf pid -> do "(a revision of "; pidLink pid; ")"
188 186 189 187 -- | List the revisions of a paste.
190 188 listRevisions :: Paste -> [Paste] -> Html
- 191 listRevisions p [] = return ()
+ 189 listRevisions _ [] = return ()
192 190 listRevisions p [x] = revisionDetails p x
193 191 listRevisions p (x:y:xs) = do
194 192 revisionDetails y x
195 193 listRevisions p (y:xs)
196 194 … … … … 209 207 " ("
210 208 linkAuthor (pasteAuthor revision)
211 209 ")"
212 210 213 211 -- | Individual paste navigation.
- 214 pasteNav :: [Language] -> [Paste] -> Paste -> Html
- 215 pasteNav langs pastes paste =
+ 212 pasteNav :: [Paste] -> Paste -> Html
+ 213 pasteNav pastes paste =
216 214 H.div ! aClass "paste-nav" $ do
217 215 diffLink
218 216 href ("/edit/" ++ pack (show pid) ++ "") ("Edit" :: Text)
219 217 " - "
220 218 href ("/annotate/" ++ pack (show pid) ++ "") ("Annotate" :: Text)
221 219 " - "
222 220 href ("/report/" ++ pack (show pid) ++ "") ("Report/Delete" :: Text)
- 223 + 221 224 222 where pid = pasteId paste
225 223 pairs = zip (drop 1 pastes) pastes
226 224 parent = fmap snd $ find ((==pid).pasteId.fst) $ pairs
227 225 diffLink = do
228 226 case listToMaybe pastes of
… … … … 237 235 " / "
238 236 href ("/diff/" ++ show prevId ++ "/" ++ show pid)
239 237 ("prev" :: Text)
240 238 case listToMaybe pastes of
241 239 Nothing -> return (); Just{} -> " - "
- 242 lang = pasteLanguage paste >>= (`lookup` ls)
- 243 ls = map (languageId &&& languageName) langs
244 240 245 241 -- | Show the paste content with highlighting.
246 242 pasteContent :: [Paste] -> [Language] -> Paste -> Html
247 243 pasteContent revisions langs paste =
248 244 case revisions of
… … … … Edit file src/Hpaste/Types/Paste.hs 33188 → 33188
41 41 ,pasteDate :: UTCTime
42 42 ,pasteAuthor :: Text
43 43 ,pasteLanguage :: Maybe LanguageId
44 44 ,pasteChannel :: Maybe ChannelId
45 45 ,pastePaste :: Text
- 46 ,pasteViews :: Integer
+ 46 ,pasteViews :: Integer
47 47 ,pasteType :: PasteType
48 48 } deriving Show
49 49 50 50 -- | The type of a paste.
51 51 data PasteType
… … … … 78 78 , pastePaste = content
79 79 , pasteDate = zonedTimeToUTC date
80 80 , pasteId = pid
81 81 , pasteViews = views
82 82 , pasteType = case annotation_of of
- 83 Just pid -> AnnotationOf pid
+ 83 Just pid' -> AnnotationOf pid'
84 84 _ -> case revision_of of
- 85 Just pid -> RevisionOf pid
+ 85 Just pid' -> RevisionOf pid'
86 86 _ -> NormalPaste
87 87 }
88 88 where (pid,title,content,author,date,views,language,channel,annotation_of,revision_of) =
89 89 convertResults field values
90 90 … … … … Edit file src/Hpaste/Types/View.hs 33188 → 33188
1 1 module Hpaste.Types.View
2 2 (Pagination(..))
3 3 where
4 4 - 5 import Data.Map (Map)
- 6 import Data.ByteString (ByteString)
+ 5 + 6 7 7 import Network.URI (URI)
8 8 9 9 -- | Pagination data.
10 10 data Pagination = Pagination {
11 11 pnPage :: Integer
… … … … Edit file src/Hpaste/Model/Paste.hs 33188 → 33188
176 176 177 177 -- | Get hints for a Haskell paste from hlint.
178 178 generateHintsForPaste :: PasteSubmit -> PasteId -> Model [Suggestion]
179 179 generateHintsForPaste PasteSubmit{..} (fromIntegral -> pid :: Integer) = io $
180 180 E.catch (generateHints (show pid) pasteSubmitPaste)
- 181 (\(SomeException e) -> return [])
+ 181 (\SomeException{} -> return [])
182 182 183 183 -- | Get hints for a Haskell paste from hlint.
184 184 generateHints :: FilePath -> Text -> IO [Suggestion]
185 185 generateHints pid contents = io $ do
186 186 tmpdir <- getTemporaryDirectory
… … … … 211 211 ,pasteSubmitPaste
212 212 ,pasteSubmitLanguage
213 213 ,pasteSubmitChannel
214 214 ,pid)
215 215 return ()
- 216 + 216 217 217 where fields = "title author content language channel"
218 218 set key = unwords [key,"=","?"]
… … … … Edit file src/Hpaste/Model/Report.hs 33188 → 33188
5 5 {-# LANGUAGE ViewPatterns #-}
6 6 7 7 -- | Report model.
8 8 9 9 module Hpaste.Model.Report
- 10 (getSomeReports,createReport,countReports)
+ 10 (getSomeReports,createReport,countReports)
11 11 where
12 12 13 13 import Hpaste.Types
14 14 import Hpaste.Model
15 15 import Hpaste.Controller.Cache
16 16 import Hpaste.Types.Cache as Key
17 17 18 18 import Control.Monad
- 19 import Control.Monad.Trans
+ 19 20 20 import Control.Monad.Env
21 21 import Control.Monad.IO
22 22 import Data.Maybe
23 23 import Data.Monoid.Operator ((++))
24 24 import qualified Data.Text.Lazy as LT
… … … … 60 60 resetCacheModel (Key.Revision (fromIntegral pid))
61 61 reset rsPaste
62 62 sendReport rs
63 63 return res
64 64 + 65 sendReport :: ReportSubmit -> Model ()
65 66 sendReport ReportSubmit{..} = do
66 67 conf <- env modelStateConfig
67 68 _ <- io $ simpleMail (configAdmin conf)
68 69 (configSiteAddy conf)
69 70 (T.pack ("Paste reported: #" ++ show rsPaste))
70 71 (LT.pack body)
71 72 (LT.pack body)
72 73 []
73 74 return ()
74 75 - 75 where body =
+ 76 where body =
76 77 "Paste " ++ show rsPaste ++ "\n\n" ++
77 78 rsComments
… … … … Edit file src/Hpaste/Controller/Cache.hs 33188 → 33188
5 5 module Hpaste.Controller.Cache
6 6 (newCache
7 7 ,cache
8 8 ,cacheIf
9 9 ,resetCache
- 10 ,resetCacheModel)
+ 10 ,resetCacheModel)
11 11 where
- 12 - 13 import Hpaste.Types (Controller,ControllerState(..))
+ 12 + 13 14 14 import Hpaste.Types.Cache
15 15 import Hpaste.Types.Config
16 16 import Hpaste.Types.MVC
17 17 18 18 import Control.Concurrent
… … … … 41 41 42 42 -- | Generate and save into the cache, or retrieve existing from the
43 43 -- | cache.
44 44 cache :: Key -> Controller (Maybe Html) -> Controller (Maybe Text)
45 45 cache key generate = do
- 46 Cache var <- asks controllerStateCache
47 46 tmpdir <- asks (configCacheDir . controllerStateConfig)
48 47 let cachePath = tmpdir ++ "/" ++ keyToString key
49 48 exists <- io $ doesFileExist cachePath
50 49 if exists
51 50 then do text <- io $ T.readFile cachePath
… … … … 61 60 resetCache key = do
62 61 tmpdir <- asks (configCacheDir . controllerStateConfig)
63 62 io $ do
64 63 let cachePath = tmpdir ++ "/" ++ keyToString key
65 64 exists <- io $ doesFileExist cachePath
- 66 when exists $ removeFile cachePath
+ 65 when exists $ removeFile cachePath
67 66 68 67 -- | Reset an item in the cache.
69 68 resetCacheModel :: Key -> Model ()
70 69 resetCacheModel key = do
71 70 tmpdir <- asks (configCacheDir . modelStateConfig)
72 71 io $ do
73 72 let cachePath = tmpdir ++ "/" ++ keyToString key
74 73 exists <- io $ doesFileExist cachePath
- 75 when exists $ removeFile cachePath
+ 74 when exists $ removeFile cachePath
76 75 77 76 keyToString :: Key -> String
78 77 keyToString Home = "home.html"
79 78 keyToString Activity = "activity.html"
80 79 keyToString (Paste i) = "paste-" ++ show i ++ ".html"
… … … … Edit file src/Hpaste/Controller/Paste.hs 33188 → 33188
13 13 where
14 14 15 15 import Hpaste.Types
16 16 17 17 import Hpaste.Controller
- 18 import Hpaste.Controller.Cache (cache,cacheIf,resetCache)
+ 18 import Hpaste.Controller.Cache (cache,resetCache)
19 19 import Hpaste.Model
20 20 import Hpaste.Model.Channel (getChannels)
21 21 import Hpaste.Model.Language (getLanguages)
22 22 import Hpaste.Model.Paste
23 23 import Hpaste.Types.Cache as Key
… … … … 110 110 111 111 -- | Get the paste id by a key.
112 112 getPasteIdKey :: ByteString -> Controller (Maybe Integer)
113 113 getPasteIdKey key = (fmap toString >=> readMay) <$> getParam key
114 114 - 115 -- | With the
+ 115 -- | With the
116 116 withPasteKey :: ByteString -> (Paste -> Controller a) -> Controller ()
117 117 withPasteKey key with = do
118 118 pid <- getPasteIdKey key
119 119 justOrGoHome pid $ \(pid :: Integer) -> do
120 120 paste <- model $ getPasteById (fromIntegral pid)
… … … …