espial/src/Handler/User.hs

173 lines
6.3 KiB
Haskell

{-# OPTIONS_GHC -fno-warn-unused-matches #-}
{-# LANGUAGE TupleSections #-}
module Handler.User where
import qualified Data.Text as T
import Handler.Common
import Import
import qualified Text.Blaze.Html5 as H
import Yesod.RssFeed
import qualified Data.Map as Map
import qualified Network.Wai.Internal as W
getUserR :: UserNameP -> Handler Html
getUserR uname=
_getUser uname SharedAll FilterAll (TagsP [])
getUserSharedR :: UserNameP -> SharedP -> Handler Html
getUserSharedR uname sharedp =
_getUser uname sharedp FilterAll (TagsP [])
getUserFilterR :: UserNameP -> FilterP -> Handler Html
getUserFilterR uname filterp =
_getUser uname SharedAll filterp (TagsP [])
getUserTagsR :: UserNameP -> TagsP -> Handler Html
getUserTagsR uname = _getUser uname SharedAll FilterAll
_getUser :: UserNameP -> SharedP -> FilterP -> TagsP -> Handler Html
_getUser unamep@(UserNameP uname) sharedp' filterp' (TagsP pathtags) = do
mauthuname <- maybeAuthUsername
(limit', page') <- lookupPagingParams
let limit = maybe 120 fromIntegral limit'
page = maybe 1 fromIntegral page'
isowner = Just uname == mauthuname
sharedp = if isowner then sharedp' else SharedPublic
filterp = case filterp' of
FilterSingle _ -> filterp'
_ -> if isowner then filterp' else FilterAll
isAll = filterp == FilterAll && sharedp == SharedAll && null pathtags
queryp = "query" :: Text
mquery <- lookupGetParam queryp
let mqueryp = fmap (queryp,) mquery
(bcount, btmarks) <- runDB $ do
Entity userId user <- getBy404 (UniqueUserName uname)
when (not isowner && userPrivacyLock user)
(redirect (AuthR LoginR))
bookmarksTagsQuery userId sharedp filterp pathtags mquery limit page
when (bcount == 0) (case filterp of FilterSingle _ -> notFound; _ -> pure ())
mroute <- getCurrentRoute
tagCloudMode <- getTagCloudMode isowner pathtags
req <- getRequest
defaultLayout do
let pager = $(widgetFile "pager")
search = $(widgetFile "search")
renderEl = "bookmarks" :: Text
tagCloudRenderEl = "tagCloud" :: Text
rssLink (UserFeedR unamep) "feed"
$(widgetFile "user")
toWidgetBody [julius|
app.dat.bmarks = #{ toJSON $ toBookmarkFormList btmarks } || [];
app.dat.isowner = #{ isowner };
app.userR = "@{UserR unamep}";
app.tagCloudMode = #{ toJSON $ tagCloudMode } || {};
|]
toWidget [julius|
setTimeout(() => {
PS.renderBookmarks('##{rawJS renderEl}')(app.dat.bmarks)();
}, 0);
setTimeout(() => {
PS.renderTagCloud('##{rawJS tagCloudRenderEl}')(app.tagCloudMode)();
}, 0);
|]
-- Form
postUserTagCloudR :: Handler ()
postUserTagCloudR = do
userId <- requireAuthId
mode <- requireCheckJsonBody
_updateTagCloudMode mode
tc <- runDB $ case mode of
TagCloudModeTop _ n -> tagCountTop userId n
TagCloudModeLowerBound _ n -> tagCountLowerBound userId n
TagCloudModeRelated _ tags -> tagCountRelated userId tags
TagCloudModeNone -> notFound
sendStatusJSON ok200 (Map.fromList tc :: Map.Map Text Int)
postUserTagCloudModeR :: Handler ()
postUserTagCloudModeR = do
userId <- requireAuthId
mode <- requireCheckJsonBody
_updateTagCloudMode mode
_updateTagCloudMode :: TagCloudMode -> Handler ()
_updateTagCloudMode mode =
case mode of
TagCloudModeTop _ _ -> setTagCloudMode mode
TagCloudModeLowerBound _ _ -> setTagCloudMode mode
TagCloudModeRelated _ _ -> setTagCloudMode mode
TagCloudModeNone -> notFound
bookmarkToRssEntry :: (Entity Bookmark, Maybe Text) -> FeedEntry Text
bookmarkToRssEntry (Entity entryId entry, tags) =
FeedEntry
{ feedEntryLink = bookmarkHref entry
, feedEntryUpdated = bookmarkTime entry
, feedEntryTitle = bookmarkDescription entry
, feedEntryContent = toHtml (bookmarkExtended entry)
, feedEntryCategories = map (EntryCategory Nothing Nothing) (maybe [] words tags)
, feedEntryEnclosure = Nothing
}
getUserFeedR :: UserNameP -> Handler RepRss
getUserFeedR unamep = do
_getUserFeed unamep SharedAll FilterAll (TagsP [])
getUserFeedSharedR :: UserNameP -> SharedP -> Handler RepRss
getUserFeedSharedR uname sharedp =
_getUserFeed uname sharedp FilterAll (TagsP [])
getUserFeedFilterR :: UserNameP -> FilterP -> Handler RepRss
getUserFeedFilterR uname filterp =
_getUserFeed uname SharedAll filterp (TagsP [])
getUserFeedTagsR :: UserNameP -> TagsP -> Handler RepRss
getUserFeedTagsR uname = _getUserFeed uname SharedAll FilterAll
_getUserFeed :: UserNameP -> SharedP -> FilterP -> TagsP -> Handler RepRss
_getUserFeed unamep@(UserNameP uname) sharedp' filterp' (TagsP pathtags) = do
mauthuname <- maybeAuthUsername
(limit', page') <- lookupPagingParams
let limit = maybe 120 fromIntegral limit'
page = maybe 1 fromIntegral page'
isowner = Just uname == mauthuname
sharedp = if isowner then sharedp' else SharedPublic
filterp = case filterp' of
FilterSingle _ -> filterp'
_ -> if isowner then filterp' else FilterAll
-- isAll = filterp == FilterAll && sharedp == SharedAll && null pathtags
queryp = "query" :: Text
mquery <- lookupGetParam queryp
(_, btmarks) <- runDB $ do
Entity userId user <- getBy404 (UniqueUserName uname)
when (not isowner && userPrivacyLock user)
(redirect (AuthR LoginR))
bookmarksTagsQuery userId sharedp filterp pathtags mquery limit page
let (descr :: Html) = toHtml $ H.text ("Bookmarks saved by " <> uname)
entries = map bookmarkToRssEntry btmarks
updated <- case maximumMay (map feedEntryUpdated entries) of
Nothing -> liftIO getCurrentTime
Just m -> return m
(feedLinkSelf, feedLinkHome) <- getFeedLinkSelf
rssFeedText $
Feed
{ feedTitle = "espial " <> uname
, feedLinkSelf = feedLinkSelf
, feedLinkHome = feedLinkHome
, feedAuthor = uname
, feedDescription = descr
, feedLanguage = "en"
, feedUpdated = updated
, feedLogo = Nothing
, feedEntries = entries
}
where
getFeedLinkSelf = do
request <- getRequest
render <- getUrlRender
let rawRequest = reqWaiRequest request
feedLinkSelf = render HomeR <> (T.drop 1 (decodeUtf8 (W.rawPathInfo rawRequest <> W.rawQueryString rawRequest)))
feedLinkHome = render (UserR unamep)
pure (feedLinkSelf, feedLinkHome)