automatic repolist updating

This commit is contained in:
Joey Hess 2012-11-13 17:50:54 -04:00
parent b7af4438f8
commit d468e37f46
14 changed files with 135 additions and 70 deletions

View file

@ -44,6 +44,7 @@ modifyDaemonStatus a = do
sendNotification $ changeNotifier s sendNotification $ changeNotifier s
return b return b
{- Returns a function that updates the lists of syncable remotes. -} {- Returns a function that updates the lists of syncable remotes. -}
calcSyncRemotes :: Annex (DaemonStatus -> DaemonStatus) calcSyncRemotes :: Annex (DaemonStatus -> DaemonStatus)
calcSyncRemotes = do calcSyncRemotes = do
@ -60,7 +61,9 @@ calcSyncRemotes = do
{- Updates the sycRemotes list from the list of all remotes in Annex state. -} {- Updates the sycRemotes list from the list of all remotes in Annex state. -}
updateSyncRemotes :: Assistant () updateSyncRemotes :: Assistant ()
updateSyncRemotes = modifyDaemonStatus_ =<< liftAnnex calcSyncRemotes updateSyncRemotes = do
modifyDaemonStatus_ =<< liftAnnex calcSyncRemotes
liftIO . sendNotification =<< syncRemotesNotifier <$> getDaemonStatus
{- Load any previous daemon status file, and store it in a MVar for this {- Load any previous daemon status file, and store it in a MVar for this
- process to use as its DaemonStatus. Also gets current transfer status. -} - process to use as its DaemonStatus. Also gets current transfer status. -}

View file

@ -72,8 +72,9 @@ reloadConfigs changedconfigs = do
sequence_ as sequence_ as
void preferredContentMapLoad void preferredContentMapLoad
{- Changes to the remote log, or the trust log, can affect the {- Changes to the remote log, or the trust log, can affect the
- syncRemotes list -} - syncRemotes list. Changes to the uuid log may affect its
when (Logs.Remote.remoteLog `elem` fs || Logs.Trust.trustLog `elem` fs) $ - display so are also included. -}
when (any (`elem` fs) [remoteLog, trustLog, uuidLog]) $
updateSyncRemotes updateSyncRemotes
where where
(fs, as) = unzip $ filter (flip S.member changedfiles . fst) (fs, as) = unzip $ filter (flip S.member changedfiles . fst)

View file

@ -47,6 +47,8 @@ data DaemonStatus = DaemonStatus
, transferNotifier :: NotificationBroadcaster , transferNotifier :: NotificationBroadcaster
-- Broadcasts notifications when there's a change to the alerts -- Broadcasts notifications when there's a change to the alerts
, alertNotifier :: NotificationBroadcaster , alertNotifier :: NotificationBroadcaster
-- Broadcasts notifications when the syncRemotes change
, syncRemotesNotifier :: NotificationBroadcaster
} }
type TransferMap = M.Map Transfer TransferInfo type TransferMap = M.Map Transfer TransferInfo
@ -70,3 +72,4 @@ newDaemonStatus = DaemonStatus
<*> newNotificationBroadcaster <*> newNotificationBroadcaster
<*> newNotificationBroadcaster <*> newNotificationBroadcaster
<*> newNotificationBroadcaster <*> newNotificationBroadcaster
<*> newNotificationBroadcaster

View file

@ -14,6 +14,7 @@ import Assistant.DaemonStatus
import Assistant.WebApp import Assistant.WebApp
import Assistant.WebApp.Types import Assistant.WebApp.Types
import Assistant.WebApp.SideBar import Assistant.WebApp.SideBar
import Assistant.WebApp.Notifications
import Assistant.WebApp.Utility import Assistant.WebApp.Utility
import Assistant.WebApp.Configurators.Local import Assistant.WebApp.Configurators.Local
import Utility.Yesod import Utility.Yesod
@ -51,7 +52,11 @@ getConfigR = ifM (inFirstRun)
introDisplay :: Text -> Widget introDisplay :: Text -> Widget
introDisplay ident = do introDisplay ident = do
webapp <- lift getYesod webapp <- lift getYesod
repolist <- lift $ repoList False True False repolist <- lift $ repoList $ RepoSelector
{ onlyCloud = False
, onlyConfigured = True
, includeHere = False
}
let n = length repolist let n = length repolist
let numrepos = show n let numrepos = show n
$(widgetFile "configurators/intro") $(widgetFile "configurators/intro")
@ -68,7 +73,11 @@ getRepositoriesR :: Handler RepHtml
getRepositoriesR = bootstrap (Just Config) $ do getRepositoriesR = bootstrap (Just Config) $ do
sideBarDisplay sideBarDisplay
setTitle "Repositories" setTitle "Repositories"
repolist <- lift $ repoList False False True let repolist = repoListDisplay $ RepoSelector
{ onlyCloud = False
, onlyConfigured = False
, includeHere = True
}
$(widgetFile "configurators/repositories") $(widgetFile "configurators/repositories")
data Actions data Actions
@ -103,16 +112,35 @@ notSyncing :: Actions -> Bool
notSyncing (SyncingRepoActions _ _) = False notSyncing (SyncingRepoActions _ _) = False
notSyncing _ = True notSyncing _ = True
repoTable :: RepoList -> Widget {- Called by client to get a list of repos, that refreshes
repoTable repolist = $(widgetFile "configurators/repositories/table") - when new repos as added.
-
- Returns a div, which will be inserted into the calling page.
-}
getRepoListR :: RepoListNotificationId -> Handler RepHtml
getRepoListR (RepoListNotificationId nid reposelector) = do
waitNotifier getRepoListBroadcaster nid
page <- widgetToPageContent $ repoListDisplay reposelector
hamletToRepHtml $ [hamlet|^{pageBody page}|]
repoListDisplay :: RepoSelector -> Widget
repoListDisplay reposelector = do
autoUpdate ident (NotifierRepoListR reposelector) (10 :: Int) (10 :: Int)
repolist <- lift $ repoList reposelector
$(widgetFile "configurators/repositories/list")
where
ident = "repolist"
type RepoList = [(String, String, Actions)] type RepoList = [(String, String, Actions)]
{- A numbered list of known repositories, {- A numbered list of known repositories,
- with actions that can be taken on them. -} - with actions that can be taken on them. -}
repoList :: Bool -> Bool -> Bool -> Handler RepoList repoList :: RepoSelector -> Handler RepoList
repoList onlycloud onlyconfigured includehere repoList reposelector
| onlyconfigured = list =<< configured | onlyConfigured reposelector = list =<< configured
| otherwise = list =<< (++) <$> configured <*> rest | otherwise = list =<< (++) <$> configured <*> rest
where where
configured = do configured = do
@ -121,7 +149,7 @@ repoList onlycloud onlyconfigured includehere
runAnnex [] $ do runAnnex [] $ do
u <- getUUID u <- getUUID
let l = map Remote.uuid rs let l = map Remote.uuid rs
let l' = if includehere then u : l else l let l' = if includeHere reposelector then u : l else l
return $ zip l' $ map mkSyncingRepoActions l' return $ zip l' $ map mkSyncingRepoActions l'
rest = runAnnex [] $ do rest = runAnnex [] $ do
m <- readRemoteLog m <- readRemoteLog
@ -134,11 +162,11 @@ repoList onlycloud onlyconfigured includehere
return $ zip unsyncable (map mkNotSyncingRepoActions unsyncable) ++ unconfigured return $ zip unsyncable (map mkNotSyncingRepoActions unsyncable) ++ unconfigured
wantedrepo r wantedrepo r
| Remote.readonly r = False | Remote.readonly r = False
| onlycloud = Git.repoIsUrl (Remote.repo r) && not (isXMPPRemote r) | onlyCloud reposelector = Git.repoIsUrl (Remote.repo r) && not (isXMPPRemote r)
| otherwise = True | otherwise = True
wantedremote Nothing = False wantedremote Nothing = False
wantedremote (Just (iscloud, _)) wantedremote (Just (iscloud, _))
| onlycloud = iscloud | onlyCloud reposelector = iscloud
| otherwise = True | otherwise = True
findinfo m u = case M.lookup u m of findinfo m u = case M.lookup u m of
Nothing -> Nothing Nothing -> Nothing

View file

@ -158,7 +158,11 @@ getFinishXMPPPairR _ = noXMPPPairing
xmppPairEnd :: Bool -> Maybe JID -> Handler RepHtml xmppPairEnd :: Bool -> Maybe JID -> Handler RepHtml
xmppPairEnd inprogress theirjid = pairPage $ do xmppPairEnd inprogress theirjid = pairPage $ do
let friend = buddyName <$> theirjid let friend = buddyName <$> theirjid
cloudrepolist <- lift $ repoList True False False let cloudrepolist = repoListDisplay $ RepoSelector
{ onlyCloud = True
, onlyConfigured = False
, includeHere = False
}
$(widgetFile "configurators/pairing/xmpp/end") $(widgetFile "configurators/pairing/xmpp/end")
#endif #endif

View file

@ -97,7 +97,7 @@ getBuddyListR :: NotificationId -> Handler RepHtml
getBuddyListR nid = do getBuddyListR nid = do
waitNotifier getBuddyListBroadcaster nid waitNotifier getBuddyListBroadcaster nid
page <- widgetToPageContent $ buddyListDisplay page <- widgetToPageContent buddyListDisplay
hamletToRepHtml $ [hamlet|^{pageBody page}|] hamletToRepHtml $ [hamlet|^{pageBody page}|]
buddyListDisplay :: Widget buddyListDisplay :: Widget

View file

@ -62,6 +62,11 @@ getNotifierSideBarR = notifierUrl SideBarR getAlertBroadcaster
getNotifierBuddyListR :: Handler RepPlain getNotifierBuddyListR :: Handler RepPlain
getNotifierBuddyListR = notifierUrl BuddyListR getBuddyListBroadcaster getNotifierBuddyListR = notifierUrl BuddyListR getBuddyListBroadcaster
getNotifierRepoListR :: RepoSelector -> Handler RepPlain
getNotifierRepoListR reposelector = notifierUrl route getRepoListBroadcaster
where
route nid = RepoListR $ RepoListNotificationId nid reposelector
getTransferBroadcaster :: Assistant NotificationBroadcaster getTransferBroadcaster :: Assistant NotificationBroadcaster
getTransferBroadcaster = transferNotifier <$> getDaemonStatus getTransferBroadcaster = transferNotifier <$> getDaemonStatus
@ -70,3 +75,6 @@ getAlertBroadcaster = alertNotifier <$> getDaemonStatus
getBuddyListBroadcaster :: Assistant NotificationBroadcaster getBuddyListBroadcaster :: Assistant NotificationBroadcaster
getBuddyListBroadcaster = getBuddyBroadcaster <$> getAssistant buddyList getBuddyListBroadcaster = getBuddyBroadcaster <$> getAssistant buddyList
getRepoListBroadcaster :: Assistant NotificationBroadcaster
getRepoListBroadcaster = syncRemotesNotifier <$> getDaemonStatus

View file

@ -62,6 +62,16 @@ data WebAppState = WebAppState
, otherRepos :: [(String, String)] -- name and path to other repos , otherRepos :: [(String, String)] -- name and path to other repos
} }
data RepoSelector = RepoSelector
{ onlyCloud :: Bool
, onlyConfigured :: Bool
, includeHere :: Bool
}
deriving (Read, Show, Eq)
data RepoListNotificationId = RepoListNotificationId NotificationId RepoSelector
deriving (Read, Show, Eq)
instance PathPiece SshData where instance PathPiece SshData where
toPathPiece = pack . show toPathPiece = pack . show
fromPathPiece = readish . unpack fromPathPiece = readish . unpack
@ -97,3 +107,11 @@ instance PathPiece BuddyKey where
instance PathPiece PairKey where instance PathPiece PairKey where
toPathPiece = pack . show toPathPiece = pack . show
fromPathPiece = readish . unpack fromPathPiece = readish . unpack
instance PathPiece RepoListNotificationId where
toPathPiece = pack . show
fromPathPiece = readish . unpack
instance PathPiece RepoSelector where
toPathPiece = pack . show
fromPathPiece = readish . unpack

View file

@ -47,6 +47,9 @@
/buddylist/#NotificationId BuddyListR GET /buddylist/#NotificationId BuddyListR GET
/notifier/buddylist NotifierBuddyListR GET /notifier/buddylist NotifierBuddyListR GET
/repolist/#RepoListNotificationId RepoListR GET
/notifier/repolist/#RepoSelector NotifierRepoListR GET
/alert/close/#AlertId CloseAlert GET /alert/close/#AlertId CloseAlert GET
/alert/click/#AlertId ClickAlert GET /alert/click/#AlertId ClickAlert GET
/filebrowser FileBrowserR GET POST /filebrowser FileBrowserR GET POST

3
debian/changelog vendored
View file

@ -2,6 +2,9 @@ git-annex (3.20121113) UNRELEASED; urgency=low
* Show error message to user when testing XMPP creds. * Show error message to user when testing XMPP creds.
* Fix build of assistant without yesod. * Fix build of assistant without yesod.
* webapp: The list of repositiories refreshes when new repositories are
added, including when new repository configurations are pushed in from
remotes.
-- Joey Hess <joeyh@debian.org> Tue, 13 Nov 2012 13:17:07 -0400 -- Joey Hess <joeyh@debian.org> Tue, 13 Nov 2012 13:17:07 -0400

View file

@ -9,38 +9,23 @@
$nothing $nothing
A pair request has been sent to all other devices using your jabber # A pair request has been sent to all other devices using your jabber #
account. account.
$else $else
Pair request accepted. Pair request accepted.
<h2> <h2>
Configure a shared cloud repository Configure a shared cloud repository
$maybe name <- friend $maybe name <- friend
<p> <p>
&#9730; To share files with #{name}, you'll need a repository in # &#9730; To share files with #{name}, you'll need a repository in #
the cloud, that you both can access. the cloud, that you both can access.
$if null cloudrepolist
<hr>
^{makeCloudRepositories}
$else
<p>
Make sure that #{name} has access to one of these cloud repositories, #
and that the repository is enabled.
^{repoTable cloudrepolist}
<hr>
Or, add a new cloud repository:
^{makeCloudRepositories}
$nothing $nothing
<p> <p>
&#9730; To share files with your other devices, when they're not # &#9730; To share files with your other devices, when they're not #
nearby, you'll need a repository in the cloud. nearby, you'll need a repository in the cloud.
$if null cloudrepolist <p>
<hr> Make sure that your other devices are configured to access a #
^{makeCloudRepositories} cloud repository, and that the same repository is enabled here #
$else too.
<p> ^{cloudrepolist}
Make sure that your other devices are configured to access one of # <h2>
these cloud repositories, and that the repository is enabled here # Add a cloud repository
too. ^{makeCloudRepositories}
^{repoTable cloudrepolist}
<hr>
Or, add a new cloud repository:
^{makeCloudRepositories}

View file

@ -1,7 +1,5 @@
<div .span9> <div .span9>
<h2> ^{repolist}
Your repositories
^{repoTable repolist}
<div .row-fluid> <div .row-fluid>
<div .span6> <div .span6>
<h2> <h2>

View file

@ -0,0 +1,36 @@
<div ##{ident}>
$if onlyCloud reposelector
$if not (null repolist)
<h2>
Cloud repositories
$else
No cloud repositories are configured yet.
$else
$if not (null repolist)
<h2>
Repositories
<table .table .table-condensed>
<tbody>
$forall (num, name, actions) <- repolist
<tr>
<td>
#{num}
<td>
#{name}
<td>
$if needsEnabled actions
<a href="@{setupRepoLink actions}">
<i .icon-warning-sign></i> not enabled
$else
<a href="@{syncToggleLink actions}">
$if notSyncing actions
<i .icon-pause></i> syncing paused
$else
<i .icon-refresh></i> syncing enabled
<td>
$if needsEnabled actions
<a href="@{setupRepoLink actions}">
enable
$else
<a href="@{setupRepoLink actions}">
configure

View file

@ -1,25 +0,0 @@
<table .table .table-condensed>
<tbody>
$forall (num, name, actions) <- repolist
<tr>
<td>
#{num}
<td>
#{name}
<td>
$if needsEnabled actions
<a href="@{setupRepoLink actions}">
<i .icon-warning-sign></i> not enabled
$else
<a href="@{syncToggleLink actions}">
$if notSyncing actions
<i .icon-pause></i> syncing paused
$else
<i .icon-refresh></i> syncing enabled
<td>
$if needsEnabled actions
<a href="@{setupRepoLink actions}">
enable
$else
<a href="@{setupRepoLink actions}">
configure