git-annex/Command/AddUrl.hs

113 lines
3.3 KiB
Haskell
Raw Normal View History

2011-07-01 21:15:46 +00:00
{- git-annex command
-
- Copyright 2011 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Command.AddUrl where
import Network.URI
2011-10-05 20:02:51 +00:00
import Common.Annex
2011-07-01 21:15:46 +00:00
import Command
import Backend
2011-07-01 21:15:46 +00:00
import qualified Command.Add
import qualified Annex
import qualified Backend.URL
import qualified Utility.Url as Url
2011-10-04 04:40:47 +00:00
import Annex.Content
import Logs.Web
import qualified Option
import Types.Key
import Types.KeySource
import Config
2011-07-01 21:15:46 +00:00
def :: [Command]
def = [notDirect $ notBareRepo $ withOptions [fileOption, pathdepthOption] $
command "addurl" (paramRepeating paramUrl) seek "add urls to annex"]
fileOption :: Option
fileOption = Option.field [] "file" paramFile "specify what file the url is added to"
2011-07-01 21:15:46 +00:00
2012-02-16 16:25:19 +00:00
pathdepthOption :: Option
2012-02-16 16:37:30 +00:00
pathdepthOption = Option.field [] "pathdepth" paramNumber "path components to use in filename"
2012-02-16 16:25:19 +00:00
2011-07-01 21:15:46 +00:00
seek :: [CommandSeek]
seek = [withField fileOption return $ \f ->
2012-02-16 16:25:19 +00:00
withField pathdepthOption (return . maybe Nothing readish) $ \d ->
withStrings $ start f d]
2011-07-01 21:15:46 +00:00
2012-02-16 16:25:19 +00:00
start :: Maybe FilePath -> Maybe Int -> String -> CommandStart
start optfile pathdepth s = go $ fromMaybe bad $ parseURI s
2012-11-12 05:05:04 +00:00
where
bad = fromMaybe (error $ "bad url " ++ s) $
parseURI $ escapeURIString isUnescapedInURI s
go url = do
let file = fromMaybe (url2file url pathdepth) optfile
showStart "addurl" file
next $ perform s file
2011-10-31 20:46:51 +00:00
2012-02-18 16:08:02 +00:00
perform :: String -> FilePath -> CommandPerform
perform url file = ifAnnexed file addurl geturl
2012-11-12 05:05:04 +00:00
where
geturl = do
liftIO $ createDirectoryIfMissing True (parentDir file)
ifM (Annex.getState Annex.fast)
( nodownload url file , download url file )
addurl (key, _backend) = do
headers <- getHttpHeaders
ifM (liftIO $ Url.check url headers $ keySize key)
( do
setUrlPresent key url
next $ return True
, do
warning $ "failed to verify url: " ++ url
stop
)
download :: String -> FilePath -> CommandPerform
download url file = do
showAction $ "downloading " ++ url ++ " "
let dummykey = Backend.URL.fromUrl url Nothing
tmp <- fromRepo $ gitAnnexTmpLocation dummykey
liftIO $ createDirectoryIfMissing True (parentDir tmp)
stopUnless (downloadUrl [url] tmp) $ do
backend <- chooseBackend file
let source = KeySource { keyFilename = file, contentLocation = tmp }
k <- genKey source backend
case k of
Nothing -> stop
Just (key, _) -> do
moveAnnex key tmp
setUrlPresent key url
next $ Command.Add.cleanup file key True
2011-07-01 21:15:46 +00:00
nodownload :: String -> FilePath -> CommandPerform
nodownload url file = do
headers <- getHttpHeaders
(exists, size) <- liftIO $ Url.exists url headers
if exists
then do
let key = Backend.URL.fromUrl url size
setUrlPresent key url
next $ Command.Add.cleanup file key False
else do
warning $ "unable to access url: " ++ url
stop
2012-02-16 16:25:19 +00:00
url2file :: URI -> Maybe Int -> FilePath
url2file url pathdepth = case pathdepth of
Nothing -> filesize $ escape fullurl
Just depth
| depth > 0 -> frombits $ drop depth
2012-02-16 18:28:17 +00:00
| depth < 0 -> frombits $ reverse . take (negate depth) . reverse
| otherwise -> error "bad --pathdepth"
2012-11-12 05:05:04 +00:00
where
fullurl = uriRegName auth ++ uriPath url ++ uriQuery url
frombits a = join "/" $ a urlbits
urlbits = map (filesize . escape) $ filter (not . null) $ split "/" fullurl
auth = fromMaybe (error $ "bad url " ++ show url) $ uriAuthority url
filesize = take 255
escape = replace "/" "_" . replace "?" "_"