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 qualified Backend
|
|
|
|
import qualified Command.Add
|
2011-07-01 22:46:07 +00:00
|
|
|
import qualified Annex
|
2011-08-06 18:57:22 +00:00
|
|
|
import qualified Backend.URL
|
2012-02-10 23:23:23 +00:00
|
|
|
import qualified Utility.Url as Url
|
2011-10-04 04:40:47 +00:00
|
|
|
import Annex.Content
|
2011-10-15 20:36:56 +00:00
|
|
|
import Logs.Web
|
2012-02-08 19:35:18 +00:00
|
|
|
import qualified Option
|
2012-02-10 23:40:36 +00:00
|
|
|
import Types.Key
|
2011-07-01 21:15:46 +00:00
|
|
|
|
2011-10-29 19:19:05 +00:00
|
|
|
def :: [Command]
|
2012-02-16 16:25:19 +00:00
|
|
|
def = [withOptions [fileOption, pathdepthOption] $
|
2012-02-08 19:35:18 +00:00
|
|
|
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]
|
2012-02-08 19:35:18 +00:00
|
|
|
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 = notBareRepo $ go $ fromMaybe bad $ parseURI s
|
2011-10-31 20:46:51 +00:00
|
|
|
where
|
2012-02-09 18:19:58 +00:00
|
|
|
bad = fromMaybe (error $ "bad url " ++ s) $
|
|
|
|
parseURI $ escapeURIString isUnescapedInURI s
|
|
|
|
go url = do
|
2012-02-16 16:25:19 +00:00
|
|
|
let file = fromMaybe (url2file url pathdepth) optfile
|
2011-07-01 21:15:46 +00:00
|
|
|
showStart "addurl" file
|
2012-02-16 16:25:19 +00:00
|
|
|
next $ perform s file pathdepth
|
2011-10-31 20:46:51 +00:00
|
|
|
|
2012-02-16 16:25:19 +00:00
|
|
|
perform :: String -> FilePath -> Maybe Int -> CommandPerform
|
|
|
|
perform url file pathdepth = ifAnnexed file addurl geturl
|
2012-02-08 19:35:18 +00:00
|
|
|
where
|
|
|
|
geturl = do
|
2012-02-16 04:05:17 +00:00
|
|
|
liftIO $ createDirectoryIfMissing True (parentDir file)
|
2012-02-08 19:35:18 +00:00
|
|
|
fast <- Annex.getState Annex.fast
|
|
|
|
if fast then nodownload url file else download url file
|
|
|
|
addurl (key, _backend) = do
|
2012-02-16 16:25:19 +00:00
|
|
|
when (pathdepth /= Nothing) $
|
|
|
|
error $ file ++ " already exists"
|
2012-02-10 23:40:36 +00:00
|
|
|
unlessM (liftIO $ Url.check url (keySize key)) $
|
|
|
|
error $ "failed to verify url: " ++ url
|
2012-02-08 19:35:18 +00:00
|
|
|
setUrlPresent key url
|
|
|
|
next $ return True
|
2011-08-06 18:57:22 +00:00
|
|
|
|
|
|
|
download :: String -> FilePath -> CommandPerform
|
|
|
|
download url file = do
|
2011-07-19 18:07:23 +00:00
|
|
|
showAction $ "downloading " ++ url ++ " "
|
2012-02-10 23:23:23 +00:00
|
|
|
let dummykey = Backend.URL.fromUrl url Nothing
|
2011-11-08 19:34:10 +00:00
|
|
|
tmp <- fromRepo $ gitAnnexTmpLocation dummykey
|
2011-07-01 22:46:07 +00:00
|
|
|
liftIO $ createDirectoryIfMissing True (parentDir tmp)
|
2012-01-02 18:20:20 +00:00
|
|
|
stopUnless (downloadUrl [url] tmp) $ do
|
2012-02-14 03:42:44 +00:00
|
|
|
backend <- Backend.chooseBackend file
|
2011-12-09 16:23:45 +00:00
|
|
|
k <- Backend.genKey tmp 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
|
|
|
|
2011-08-06 18:57:22 +00:00
|
|
|
nodownload :: String -> FilePath -> CommandPerform
|
|
|
|
nodownload url file = do
|
2012-02-10 23:23:23 +00:00
|
|
|
(exists, size) <- liftIO $ Url.exists url
|
|
|
|
unless exists $
|
|
|
|
error $ "unable to access url: " ++ url
|
|
|
|
let key = Backend.URL.fromUrl url size
|
2011-10-15 20:36:56 +00:00
|
|
|
setUrlPresent key url
|
2011-08-06 18:57:22 +00:00
|
|
|
next $ Command.Add.cleanup file key False
|
|
|
|
|
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
|
2012-02-16 18:26:53 +00:00
|
|
|
| depth > 0 -> frombits $ drop depth
|
|
|
|
| otherwise -> frombits $ reverse . take (negate depth) . reverse
|
2011-07-01 21:15:46 +00:00
|
|
|
where
|
2012-02-16 16:25:19 +00:00
|
|
|
fullurl = uriRegName auth ++ uriPath url ++ uriQuery url
|
2012-02-16 18:26:53 +00:00
|
|
|
frombits a = filesize $ join "/" $ a urlbits
|
|
|
|
urlbits = map escape $ filter (not . null) $ split "/" fullurl
|
2011-09-07 23:04:51 +00:00
|
|
|
auth = fromMaybe (error $ "bad url " ++ show url) $ uriAuthority url
|
2012-02-16 16:25:19 +00:00
|
|
|
filesize = take 255
|
|
|
|
escape = replace "/" "_" . replace "?" "_"
|