2012-07-31 05:11:32 +00:00
|
|
|
{- git-annex assistant webapp dashboard
|
|
|
|
-
|
|
|
|
- Copyright 2012 Joey Hess <joey@kitenet.net>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
2012-08-03 13:44:43 +00:00
|
|
|
{-# LANGUAGE CPP, TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes #-}
|
2012-07-31 05:11:32 +00:00
|
|
|
|
|
|
|
module Assistant.WebApp.DashBoard where
|
|
|
|
|
|
|
|
import Assistant.Common
|
|
|
|
import Assistant.WebApp
|
|
|
|
import Assistant.WebApp.SideBar
|
|
|
|
import Assistant.WebApp.Notifications
|
|
|
|
import Assistant.WebApp.Configurators
|
|
|
|
import Assistant.DaemonStatus
|
|
|
|
import Assistant.TransferQueue
|
|
|
|
import Utility.NotificationBroadcaster
|
|
|
|
import Utility.Yesod
|
|
|
|
import Logs.Transfer
|
|
|
|
import Utility.Percentage
|
|
|
|
import Utility.DataUnits
|
|
|
|
import Types.Key
|
|
|
|
import qualified Remote
|
2012-08-03 13:44:43 +00:00
|
|
|
import qualified Git
|
2012-07-31 05:11:32 +00:00
|
|
|
|
|
|
|
import Yesod
|
|
|
|
import Text.Hamlet
|
|
|
|
import qualified Data.Map as M
|
2012-08-03 14:18:57 +00:00
|
|
|
import Control.Concurrent
|
2012-08-08 21:55:56 +00:00
|
|
|
import System.Posix.Signals (signalProcess, sigTERM, sigKILL)
|
2012-07-31 05:11:32 +00:00
|
|
|
|
|
|
|
{- A display of currently running and queued transfers.
|
|
|
|
-
|
|
|
|
- Or, if there have never been any this run, an intro display. -}
|
|
|
|
transfersDisplay :: Bool -> Widget
|
|
|
|
transfersDisplay warnNoScript = do
|
|
|
|
webapp <- lift getYesod
|
2012-07-31 15:19:40 +00:00
|
|
|
current <- lift $ runAnnex [] $
|
2012-07-31 05:11:32 +00:00
|
|
|
M.toList . currentTransfers
|
|
|
|
<$> liftIO (getDaemonStatus $ daemonStatus webapp)
|
|
|
|
queued <- liftIO $ getTransferQueue $ transferQueue webapp
|
|
|
|
let ident = "transfers"
|
|
|
|
autoUpdate ident NotifierTransfersR (10 :: Int) (10 :: Int)
|
2012-08-08 20:06:01 +00:00
|
|
|
let transfers = current ++ queued ++ dummy
|
2012-07-31 05:11:32 +00:00
|
|
|
if null transfers
|
|
|
|
then ifM (lift $ showIntro <$> getWebAppState)
|
|
|
|
( introDisplay ident
|
2012-07-31 05:24:49 +00:00
|
|
|
, $(widgetFile "dashboard/transfers")
|
2012-07-31 05:11:32 +00:00
|
|
|
)
|
2012-07-31 05:24:49 +00:00
|
|
|
else $(widgetFile "dashboard/transfers")
|
2012-08-08 20:06:01 +00:00
|
|
|
where
|
|
|
|
dummy = [(t, i), (t, i)]
|
|
|
|
t = Transfer Download (UUID "00000000-0000-0000-0000-000000000001") k
|
|
|
|
k = Types.Key.Key "foo" "bar" Nothing Nothing
|
|
|
|
i = TransferInfo Nothing Nothing Nothing Nothing Nothing Nothing
|
2012-07-31 05:11:32 +00:00
|
|
|
|
|
|
|
{- Called by client to get a display of currently in process transfers.
|
|
|
|
-
|
|
|
|
- Returns a div, which will be inserted into the calling page.
|
|
|
|
-
|
|
|
|
- Note that the head of the widget is not included, only its
|
|
|
|
- body is. To get the widget head content, the widget is also
|
|
|
|
- inserted onto the getHomeR page.
|
|
|
|
-}
|
|
|
|
getTransfersR :: NotificationId -> Handler RepHtml
|
|
|
|
getTransfersR nid = do
|
|
|
|
waitNotifier transferNotifier nid
|
|
|
|
|
|
|
|
page <- widgetToPageContent $ transfersDisplay False
|
|
|
|
hamletToRepHtml $ [hamlet|^{pageBody page}|]
|
|
|
|
|
|
|
|
{- The main dashboard. -}
|
|
|
|
dashboard :: Bool -> Widget
|
|
|
|
dashboard warnNoScript = do
|
2012-08-04 00:40:34 +00:00
|
|
|
sideBarDisplay
|
2012-07-31 05:11:32 +00:00
|
|
|
let content = transfersDisplay warnNoScript
|
2012-07-31 05:24:49 +00:00
|
|
|
$(widgetFile "dashboard/main")
|
2012-07-31 05:11:32 +00:00
|
|
|
|
|
|
|
getHomeR :: Handler RepHtml
|
2012-07-31 18:23:17 +00:00
|
|
|
getHomeR = ifM (inFirstRun)
|
|
|
|
( redirect ConfigR
|
|
|
|
, bootstrap (Just DashBoard) $ dashboard True
|
|
|
|
)
|
2012-07-31 06:30:26 +00:00
|
|
|
|
|
|
|
{- Same as HomeR, except no autorefresh at all (and no noscript warning). -}
|
|
|
|
getNoScriptR :: Handler RepHtml
|
2012-07-31 18:23:17 +00:00
|
|
|
getNoScriptR = bootstrap (Just DashBoard) $ dashboard False
|
2012-07-31 05:11:32 +00:00
|
|
|
|
|
|
|
{- Same as HomeR, except with autorefreshing via meta refresh. -}
|
|
|
|
getNoScriptAutoR :: Handler RepHtml
|
2012-07-31 06:30:26 +00:00
|
|
|
getNoScriptAutoR = bootstrap (Just DashBoard) $ do
|
2012-07-31 05:11:32 +00:00
|
|
|
let ident = NoScriptR
|
|
|
|
let delayseconds = 3 :: Int
|
|
|
|
let this = NoScriptAutoR
|
2012-07-31 05:24:49 +00:00
|
|
|
toWidgetHead $(hamletFile $ hamletTemplate "dashboard/metarefresh")
|
2012-07-31 05:11:32 +00:00
|
|
|
dashboard False
|
2012-08-03 13:44:43 +00:00
|
|
|
|
|
|
|
{- The javascript code does a post. -}
|
|
|
|
postFileBrowserR :: Handler ()
|
|
|
|
postFileBrowserR = void openFileBrowser
|
|
|
|
|
|
|
|
{- Used by non-javascript browsers, where clicking on the link actually
|
|
|
|
- opens this page, so we redirect back to the referrer. -}
|
|
|
|
getFileBrowserR :: Handler ()
|
2012-08-08 20:06:01 +00:00
|
|
|
getFileBrowserR = whenM openFileBrowser $ redirectBack
|
|
|
|
|
|
|
|
redirectBack :: Handler ()
|
|
|
|
redirectBack = do
|
2012-08-03 13:44:43 +00:00
|
|
|
clearUltDest
|
|
|
|
setUltDestReferer
|
|
|
|
redirectUltDest HomeR
|
|
|
|
|
|
|
|
{- Opens the system file browser on the repo, or, as a fallback,
|
|
|
|
- goes to a file:// url. Returns True if it's ok to redirect away
|
2012-08-03 14:18:57 +00:00
|
|
|
- from the page (ie, the system file browser was opened).
|
|
|
|
-
|
|
|
|
- Note that the command is opened using a different thread, to avoid
|
|
|
|
- blocking the response to the browser on it. -}
|
2012-08-03 13:44:43 +00:00
|
|
|
openFileBrowser :: Handler Bool
|
|
|
|
openFileBrowser = do
|
|
|
|
path <- runAnnex (error "no configured repository") $
|
|
|
|
fromRepo Git.repoPath
|
2012-08-03 14:18:57 +00:00
|
|
|
ifM (liftIO $ inPath cmd <&&> inPath cmd)
|
|
|
|
( do
|
|
|
|
void $ liftIO $ forkIO $ void $
|
|
|
|
boolSystem cmd [Param path]
|
|
|
|
return True
|
2012-08-03 13:44:43 +00:00
|
|
|
, do
|
|
|
|
clearUltDest
|
|
|
|
setUltDest $ "file://" ++ path
|
|
|
|
void $ redirectUltDest HomeR
|
|
|
|
return False
|
|
|
|
)
|
|
|
|
where
|
|
|
|
#if OSX
|
|
|
|
cmd = "open"
|
|
|
|
#else
|
|
|
|
cmd = "xdg-open"
|
|
|
|
#endif
|
2012-08-08 20:06:01 +00:00
|
|
|
|
|
|
|
{- Transfer controls. The GET is done in noscript mode and redirects back
|
|
|
|
- to the referring page. The POST is called by javascript. -}
|
|
|
|
getPauseTransferR :: Transfer -> Handler ()
|
|
|
|
getPauseTransferR t = pauseTransfer t >> redirectBack
|
|
|
|
postPauseTransferR :: Transfer -> Handler ()
|
|
|
|
postPauseTransferR t = pauseTransfer t
|
|
|
|
getStartTransferR :: Transfer -> Handler ()
|
|
|
|
getStartTransferR t = startTransfer t >> redirectBack
|
|
|
|
postStartTransferR :: Transfer -> Handler ()
|
|
|
|
postStartTransferR t = startTransfer t
|
|
|
|
getCancelTransferR :: Transfer -> Handler ()
|
|
|
|
getCancelTransferR t = cancelTransfer t >> redirectBack
|
|
|
|
postCancelTransferR :: Transfer -> Handler ()
|
|
|
|
postCancelTransferR t = cancelTransfer t
|
|
|
|
|
|
|
|
pauseTransfer :: Transfer -> Handler ()
|
|
|
|
pauseTransfer t = liftIO $ putStrLn "pause"
|
|
|
|
|
|
|
|
startTransfer :: Transfer -> Handler ()
|
|
|
|
startTransfer t = liftIO $ putStrLn "start"
|
|
|
|
|
|
|
|
cancelTransfer :: Transfer -> Handler ()
|
2012-08-08 21:55:56 +00:00
|
|
|
cancelTransfer t = do
|
|
|
|
webapp <- getYesod
|
|
|
|
{- Remove if queued. -}
|
|
|
|
void $ liftIO $ dequeueTransfer (transferQueue webapp) t
|
|
|
|
{- When the transfer is running, don't directly remove it from the
|
|
|
|
- map, instead signal to end the transfer, and rely on the
|
|
|
|
- TransferWatcher to notice it's done and update the map. -}
|
|
|
|
mi <- liftIO $ M.lookup t . currentTransfers
|
|
|
|
<$> getDaemonStatus (daemonStatus webapp)
|
|
|
|
case mi of
|
|
|
|
Just (TransferInfo { transferTid = Just tid } ) -> do
|
|
|
|
-- TODO
|
|
|
|
error "TODO"
|
|
|
|
Just (TransferInfo { transferPid = Just pid } ) -> liftIO $ do
|
|
|
|
signalProcess sigTERM pid
|
|
|
|
threadDelay 500000 -- half a second grace period
|
|
|
|
signalProcess sigKILL pid
|
|
|
|
_ -> noop
|