honor annex.diskreserve when running youtube-dl

This commit was sponsored by André Pereira on Patreon.
This commit is contained in:
Joey Hess 2017-11-30 16:08:30 -04:00
parent 67ab567bc7
commit 1228fe8c86
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 69 additions and 36 deletions

View file

@ -21,6 +21,7 @@ module Annex.Content (
prepTmp, prepTmp,
withTmp, withTmp,
checkDiskSpace, checkDiskSpace,
needMoreDiskSpace,
moveAnnex, moveAnnex,
populatePointerFile, populatePointerFile,
linkToAnnex, linkToAnnex,
@ -431,16 +432,17 @@ checkDiskSpace' need destdir key alreadythere samefilesystem = ifM (Annex.getSta
let delta = need + reserve - have - alreadythere + inprogress let delta = need + reserve - have - alreadythere + inprogress
let ok = delta <= 0 let ok = delta <= 0
unless ok $ unless ok $
needmorespace delta warning $ needMoreDiskSpace delta
return ok return ok
_ -> return True _ -> return True
) )
where where
dir = maybe (fromRepo gitAnnexDir) return destdir dir = maybe (fromRepo gitAnnexDir) return destdir
needmorespace n =
warning $ "not enough free space, need " ++ needMoreDiskSpace :: Integer -> String
roughSize storageUnits True n ++ needMoreDiskSpace n = "not enough free space, need " ++
" more" ++ forcemsg roughSize storageUnits True n ++ " more" ++ forcemsg
where
forcemsg = " (use --force to override this check or adjust annex.diskreserve)" forcemsg = " (use --force to override this check or adjust annex.diskreserve)"
{- Moves a key's content into .git/annex/objects/ {- Moves a key's content into .git/annex/objects/

View file

@ -11,6 +11,8 @@ import Annex.Common
import qualified Annex import qualified Annex
import Annex.Content import Annex.Content
import Utility.Url (URLString) import Utility.Url (URLString)
import Utility.DiskFree
import Logs.Transfer
-- Runs youtube-dl in a work directory, to download a single media file -- Runs youtube-dl in a work directory, to download a single media file
-- from the url. Reutrns the path to the media file in the work directory. -- from the url. Reutrns the path to the media file in the work directory.
@ -26,41 +28,70 @@ import Utility.Url (URLString)
-- (Note that we can't use --output to specifiy the file to download to, -- (Note that we can't use --output to specifiy the file to download to,
-- due to <https://github.com/rg3/youtube-dl/issues/14864>) -- due to <https://github.com/rg3/youtube-dl/issues/14864>)
youtubeDl :: URLString -> FilePath -> Annex (Either String (Maybe FilePath)) youtubeDl :: URLString -> FilePath -> Annex (Either String (Maybe FilePath))
youtubeDl url workdir = ifM (liftIO (inPath "youtube-dl") <&&> runcmd) youtubeDl url workdir = ifM (liftIO $ inPath "youtube-dl")
( do ( runcmd >>= \case
fs <- liftIO $ filterM (doesFileExist) =<< dirContents workdir Right True -> do
case fs of fs <- liftIO $ filterM (doesFileExist) =<< dirContents workdir
(f:[]) -> return (Right (Just f)) case fs of
[] -> return nofiles (f:[]) -> return (Right (Just f))
_ -> return (toomanyfiles fs) [] -> return nofiles
, do _ -> return (toomanyfiles fs)
fs <- liftIO $ filterM (doesFileExist) =<< dirContents workdir Right False -> do
if null fs fs <- liftIO $ filterM (doesFileExist) =<< dirContents workdir
then return (Right Nothing) if null fs
else return (Left "youtube-dl download is incomplete. Run the command again to resume.") then return (Right Nothing)
else return (Left "youtube-dl download is incomplete. Run the command again to resume.")
Left msg -> return (Left msg)
, return (Right Nothing)
) )
where where
nofiles = Left "youtube-dl did not put any media in its work directory, perhaps it's been configured to store files somewhere else?" nofiles = Left "youtube-dl did not put any media in its work directory, perhaps it's been configured to store files somewhere else?"
toomanyfiles fs = Left $ "youtube-dl downloaded multiple media files; git-annex is only able to deal with one per url: " ++ show fs toomanyfiles fs = Left $ "youtube-dl downloaded multiple media files; git-annex is only able to deal with one per url: " ++ show fs
runcmd = do runcmd = youtubeDlMaxSize workdir >>= \case
quiet <- commandProgressDisabled Left msg -> return (Left msg)
opts <- youtubeDlOpts $ Right maxsize -> do
[ Param url quiet <- commandProgressDisabled
-- To make youtube-dl only download one file, opts <- youtubeDlOpts $ dlopts ++ maxsize ++
-- when given a page with a video and a playlist, if quiet then [ Param "--quiet" ] else []
-- download only the video. ok <- liftIO $ boolSystem' "youtube-dl" opts $
, Param "--no-playlist" \p -> p { cwd = Just workdir }
-- And when given a page with only a playlist, return (Right ok)
-- download only the first video on the playlist. dlopts =
-- (Assumes the video is somewhat stable, but [ Param url
-- this is the only way to prevent youtube-dl -- To make youtube-dl only download one file when given a
-- from downloading the whole playlist.) -- page with a video and a playlist, download only the video.
, Param "--playlist-items", Param "0" , Param "--no-playlist"
-- TODO --max-filesize -- And when given a page with only a playlist, download only
] ++ -- the first video on the playlist. (Assumes the video is
if quiet then [ Param "--quiet" ] else [] -- somewhat stable, but this is the only way to prevent
liftIO $ boolSystem' "youtube-dl" opts $ -- youtube-dl from downloading the whole playlist.)
\p -> p { cwd = Just workdir } , Param "--playlist-items", Param "0"
]
-- To honor annex.diskreserve, ask youtube-dl to not download too
-- large a media file. Factors in other downloads that are in progress,
-- and any files in the workdir that it may have partially downloaded
-- before.
youtubeDlMaxSize :: FilePath -> Annex (Either String [CommandParam])
youtubeDlMaxSize workdir = ifM (Annex.getState Annex.force)
( return $ Right []
, liftIO (getDiskFree workdir) >>= \case
Just have -> do
inprogress <- sizeOfDownloadsInProgress (const True)
partial <- liftIO $ sum
<$> (mapM getFileSize =<< dirContents workdir)
reserve <- annexDiskReserve <$> Annex.getGitConfig
let maxsize = have - reserve - inprogress + partial
if maxsize > 0
then return $ Right
[ Param "--max-filesize"
, Param (show maxsize)
]
else return $ Left $
needMoreDiskSpace $
negate maxsize + 1024
Nothing -> return $ Right []
)
-- Download a media file to a destination, -- Download a media file to a destination,
youtubeDlTo :: Key -> URLString -> FilePath -> Annex Bool youtubeDlTo :: Key -> URLString -> FilePath -> Annex Bool