let url claims optionally include a suggested filename

This commit is contained in:
Joey Hess 2014-12-11 12:47:57 -04:00
parent 7c9149a44f
commit 85df9c30e9
11 changed files with 67 additions and 26 deletions

29
Annex/URLClaim.hs Normal file
View file

@ -0,0 +1,29 @@
{- Url claim checking.
-
- Copyright 2013-2014 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Annex.URLClaim (
URLClaim(..),
urlClaim
) where
import Common.Annex
import Types.URLClaim
import Logs.Web
import Remote
import qualified Types.Remote as Remote
urlClaim :: URLString -> Annex (Remote, URLClaim)
urlClaim url = do
rs <- remoteList
-- The web special remote claims urls by default.
let web = Prelude.head $ filter (\r -> uuid r == webUUID) rs
fromMaybe (web, URLClaimed) <$> getM (\r -> ret r <$> checkclaim r) rs
where
checkclaim = maybe (pure Nothing) (flip id url) . Remote.claimUrl
ret _ Nothing = Nothing
ret r (Just c) = Just (r, c)

View file

@ -21,6 +21,7 @@ import qualified Annex.Url as Url
import qualified Backend.URL import qualified Backend.URL
import qualified Remote import qualified Remote
import qualified Types.Remote as Remote import qualified Types.Remote as Remote
import Annex.URLClaim
import Annex.Content import Annex.Content
import Logs.Web import Logs.Web
import Types.Key import Types.Key
@ -58,23 +59,23 @@ seek ps = do
start :: Bool -> Maybe FilePath -> Maybe Int -> String -> CommandStart start :: Bool -> Maybe FilePath -> Maybe Int -> String -> CommandStart
start relaxed optfile pathdepth s = do start relaxed optfile pathdepth s = do
r <- Remote.claimingUrl s (r, claim) <- urlClaim s
if Remote.uuid r == webUUID if Remote.uuid r == webUUID
then startWeb relaxed optfile pathdepth s then startWeb relaxed optfile pathdepth s
else startRemote r relaxed optfile pathdepth s else startRemote r claim relaxed optfile pathdepth s
startRemote :: Remote -> Bool -> Maybe FilePath -> Maybe Int -> String -> CommandStart startRemote :: Remote -> URLClaim -> Bool -> Maybe FilePath -> Maybe Int -> String -> CommandStart
startRemote r relaxed optfile pathdepth s = do startRemote r claim relaxed optfile pathdepth s = do
url <- case Url.parseURIRelaxed s of url <- case Url.parseURIRelaxed s of
Nothing -> error $ "bad uri " ++ s Nothing -> error $ "bad uri " ++ s
Just u -> pure u Just u -> pure u
pathmax <- liftIO $ fileNameLengthLimit "." pathmax <- liftIO $ fileNameLengthLimit "."
let file = choosefile $ url2file url pathdepth pathmax let file = flip fromMaybe optfile $ case claim of
URLClaimedAs f -> f
URLClaimed -> url2file url pathdepth pathmax
showStart "addurl" file showStart "addurl" file
showNote $ "using " ++ Remote.name r showNote $ "using " ++ Remote.name r
next $ performRemote r relaxed s file next $ performRemote r relaxed s file
where
choosefile = flip fromMaybe optfile
performRemote :: Remote -> Bool -> URLString -> FilePath -> CommandPerform performRemote :: Remote -> Bool -> URLString -> FilePath -> CommandPerform
performRemote r relaxed uri file = ifAnnexed file adduri geturi performRemote r relaxed uri file = ifAnnexed file adduri geturi

View file

@ -16,6 +16,7 @@ import qualified Command.Add
import Logs.Web import Logs.Web
import Logs.Location import Logs.Location
import Utility.CopyFile import Utility.CopyFile
import Annex.URLClaim
import qualified Remote import qualified Remote
cmd :: [Command] cmd :: [Command]
@ -63,7 +64,7 @@ cleanup file oldkey newkey = do
-- the new key as well. -- the new key as well.
urls <- getUrls oldkey urls <- getUrls oldkey
forM_ urls $ \url -> do forM_ urls $ \url -> do
r <- Remote.claimingUrl url r <- fst <$> urlClaim url
setUrlPresent (Remote.uuid r) newkey url setUrlPresent (Remote.uuid r) newkey url
-- Update symlink to use the new key. -- Update symlink to use the new key.

View file

@ -10,6 +10,7 @@ module Command.RmUrl where
import Common.Annex import Common.Annex
import Command import Command
import Logs.Web import Logs.Web
import Annex.URLClaim
import qualified Remote import qualified Remote
cmd :: [Command] cmd :: [Command]
@ -27,7 +28,7 @@ start (file, url) = flip whenAnnexed file $ \_ key -> do
cleanup :: String -> Key -> CommandCleanup cleanup :: String -> Key -> CommandCleanup
cleanup url key = do cleanup url key = do
r <- Remote.claimingUrl url r <- fst <$> urlClaim url
let url' = if Remote.uuid r == webUUID let url' = if Remote.uuid r == webUUID
then url then url
else setDownloader url OtherDownloader else setDownloader url OtherDownloader

View file

@ -14,6 +14,7 @@ import Command
import Remote import Remote
import Logs.Trust import Logs.Trust
import Logs.Web import Logs.Web
import Annex.URLClaim
cmd :: [Command] cmd :: [Command]
cmd = [noCommit $ withOptions (jsonOption : keyOptions) $ cmd = [noCommit $ withOptions (jsonOption : keyOptions) $
@ -71,4 +72,4 @@ performRemote key remote = do
. filter (\(_, d) -> d == OtherDownloader) . filter (\(_, d) -> d == OtherDownloader)
. map getDownloader . map getDownloader
<$> getUrls key <$> getUrls key
filterM (\u -> (==) <$> pure remote <*> claimingUrl u) us filterM (\u -> (==) <$> pure remote <*> (fst <$> urlClaim u)) us

View file

@ -46,7 +46,6 @@ module Remote (
logStatus, logStatus,
checkAvailable, checkAvailable,
isXMPPRemote, isXMPPRemote,
claimingUrl,
) where ) where
import qualified Data.Map as M import qualified Data.Map as M
@ -61,7 +60,6 @@ import Annex.UUID
import Logs.UUID import Logs.UUID
import Logs.Trust import Logs.Trust
import Logs.Location hiding (logStatus) import Logs.Location hiding (logStatus)
import Logs.Web
import Remote.List import Remote.List
import Config import Config
import Git.Types (RemoteName) import Git.Types (RemoteName)
@ -320,12 +318,3 @@ hasKey r k = either (Left . show) Right <$> tryNonAsync (checkPresent r k)
hasKeyCheap :: Remote -> Bool hasKeyCheap :: Remote -> Bool
hasKeyCheap = checkPresentCheap hasKeyCheap = checkPresentCheap
{- The web special remote claims urls by default. -}
claimingUrl :: URLString -> Annex Remote
claimingUrl url = do
rs <- remoteList
let web = Prelude.head $ filter (\r -> uuid r == webUUID) rs
fromMaybe web <$> firstM checkclaim rs
where
checkclaim = maybe (pure False) (flip id url) . claimUrl

View file

@ -12,6 +12,7 @@ import qualified Annex
import Common.Annex import Common.Annex
import Types.Remote import Types.Remote
import Types.CleanupActions import Types.CleanupActions
import Types.URLClaim
import qualified Git import qualified Git
import Config import Config
import Remote.Helper.Special import Remote.Helper.Special
@ -421,12 +422,13 @@ getAvailability external r gc = maybe query return (remoteAnnexAvailability gc)
setRemoteAvailability r avail setRemoteAvailability r avail
return avail return avail
claimurl :: External -> URLString -> Annex Bool claimurl :: External -> URLString -> Annex (Maybe URLClaim)
claimurl external url = claimurl external url =
handleRequest external (CLAIMURL url) Nothing $ \req -> case req of handleRequest external (CLAIMURL url) Nothing $ \req -> case req of
CLAIMURL_SUCCESS -> Just $ return True CLAIMURL_SUCCESS -> Just $ return $ Just URLClaimed
CLAIMURL_FAILURE -> Just $ return False (CLAIMURL_AS f) -> Just $ return $ Just $ URLClaimedAs f
UNSUPPORTED_REQUEST -> Just $ return False CLAIMURL_FAILURE -> Just $ return Nothing
UNSUPPORTED_REQUEST -> Just $ return Nothing
_ -> Nothing _ -> Nothing
checkurl :: External -> URLString -> Annex (Maybe Integer) checkurl :: External -> URLString -> Annex (Maybe Integer)

View file

@ -136,6 +136,7 @@ data Response
| INITREMOTE_SUCCESS | INITREMOTE_SUCCESS
| INITREMOTE_FAILURE ErrorMsg | INITREMOTE_FAILURE ErrorMsg
| CLAIMURL_SUCCESS | CLAIMURL_SUCCESS
| CLAIMURL_AS FilePath
| CLAIMURL_FAILURE | CLAIMURL_FAILURE
| CHECKURL_SIZE Size | CHECKURL_SIZE Size
| CHECKURL_SIZEUNKNOWN | CHECKURL_SIZEUNKNOWN
@ -158,6 +159,7 @@ instance Proto.Receivable Response where
parseCommand "INITREMOTE-SUCCESS" = Proto.parse0 INITREMOTE_SUCCESS parseCommand "INITREMOTE-SUCCESS" = Proto.parse0 INITREMOTE_SUCCESS
parseCommand "INITREMOTE-FAILURE" = Proto.parse1 INITREMOTE_FAILURE parseCommand "INITREMOTE-FAILURE" = Proto.parse1 INITREMOTE_FAILURE
parseCommand "CLAIMURL-SUCCESS" = Proto.parse0 CLAIMURL_SUCCESS parseCommand "CLAIMURL-SUCCESS" = Proto.parse0 CLAIMURL_SUCCESS
parseCommand "CLAIMURL-AS" = Proto.parse1 CLAIMURL_AS
parseCommand "CLAIMURL-FAILURE" = Proto.parse0 CLAIMURL_FAILURE parseCommand "CLAIMURL-FAILURE" = Proto.parse0 CLAIMURL_FAILURE
parseCommand "CHECKURL-SIZE" = Proto.parse1 CHECKURL_SIZE parseCommand "CHECKURL-SIZE" = Proto.parse1 CHECKURL_SIZE
parseCommand "CHECKURL-SIZEUNKNOWN" = Proto.parse0 CHECKURL_SIZEUNKNOWN parseCommand "CHECKURL-SIZEUNKNOWN" = Proto.parse0 CHECKURL_SIZEUNKNOWN

View file

@ -25,6 +25,7 @@ import Types.UUID
import Types.GitConfig import Types.GitConfig
import Types.Availability import Types.Availability
import Types.Creds import Types.Creds
import Types.URLClaim
import Config.Cost import Config.Cost
import Utility.Metered import Utility.Metered
import Git.Types import Git.Types
@ -103,7 +104,7 @@ data RemoteA a = Remote {
-- Information about the remote, for git annex info to display. -- Information about the remote, for git annex info to display.
getInfo :: a [(String, String)], getInfo :: a [(String, String)],
-- Some remotes can download from an url (or uri). -- Some remotes can download from an url (or uri).
claimUrl :: Maybe (URLString -> a Bool), claimUrl :: Maybe (URLString -> a (Maybe URLClaim)),
-- Checks that the url is accessible, and gets the size of its -- Checks that the url is accessible, and gets the size of its
-- content. Returns Nothing if the url is accessible, but -- content. Returns Nothing if the url is accessible, but
-- its size cannot be determined inexpensively. -- its size cannot be determined inexpensively.

11
Types/URLClaim.hs Normal file
View file

@ -0,0 +1,11 @@
{- git-annex url claiming
-
- Copyright 2014 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Types.URLClaim where
data URLClaim = URLClaimed | URLClaimedAs FilePath
deriving (Eq)

View file

@ -179,6 +179,9 @@ while it's handling a request.
Indicates that INITREMOTE failed. Indicates that INITREMOTE failed.
* `CLAIMURL-SUCCESS` * `CLAIMURL-SUCCESS`
Indicates that the CLAIMURL url will be handled by this remote. Indicates that the CLAIMURL url will be handled by this remote.
* `CLAIMURL-AS Filename`
Indicates that the CLAIMURL url will be handled by this remote,
and suggests a filename to use for it.
* `CLAIMURL-FAILURE` * `CLAIMURL-FAILURE`
Indicates that the CLAIMURL url wil not be handled by this remote. Indicates that the CLAIMURL url wil not be handled by this remote.
* `CHECKURL-SIZE Size` * `CHECKURL-SIZE Size`