From 2315b69d13915dee1ecf706d6e65b958d158c8c0 Mon Sep 17 00:00:00 2001 From: Stuart Terrett Date: Mon, 12 Nov 2018 16:14:03 -0500 Subject: [PATCH] Outline program --- app/Main.hs | 28 +++++++++++++++++++++++++--- escape-from-itunes.cabal | 1 + src/Actions.hs | 6 ++++-- src/Args.hs | 2 +- src/Channel.hs | 11 ++++++----- src/Itunes.hs | 8 +++++++- stack.yaml | 1 + 7 files changed, 45 insertions(+), 12 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index 18ee430..f8b0ca7 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -1,14 +1,36 @@ module Main where +import Control.Concurrent.Async (race_) +import GHC.Conc.Sync (atomically, STM) import Options.Applicative (execParser) import Args import Itunes +import Actions (getAction) +import Channel main :: IO () main = execParser app >>= run run :: Args -> IO () -run = putStrLn . show +run args = let + action = getAction (actionType args) + channel = newChannel 500 -- wild ass guess + transform = mkTransform (target args) (attributes args) + in + (race_ (readSources channel transform [source args]) + (doAction channel action)) >> + putStrLn "finished" -escape :: Transform -> Action -> [Directory] -> IO () -escape = undefined +readSources :: STM (Channel Copy) -> Transform -> [Directory] -> IO () +readSources _ _ [] = return () +readSources chan t (d:ds) = do + (dirs, copies) <- handleDirectory d t + atomically $ enqueueCopies chan copies + readSources chan t (ds ++ dirs) + +enqueueCopies :: STM (Channel Copy) -> [Copy] -> STM () +enqueueCopies chan cs = chan >>= writeChan cs + +doAction :: STM (Channel Copy) -> Action -> IO () +doAction chan action = + atomically (chan >>= readChan) >>= action diff --git a/escape-from-itunes.cabal b/escape-from-itunes.cabal index 63825d0..0bed8bd 100644 --- a/escape-from-itunes.cabal +++ b/escape-from-itunes.cabal @@ -37,6 +37,7 @@ executable escape-from-itunes build-depends: base , escape-from-itunes , optparse-applicative == 0.14.3.0 + , async == 2.2.1 default-language: Haskell2010 test-suite escape-from-itunes-test diff --git a/src/Actions.hs b/src/Actions.hs index da7f11f..07ade28 100644 --- a/src/Actions.hs +++ b/src/Actions.hs @@ -1,7 +1,8 @@ module Actions where import Itunes (Copy (Copy)) -import System.Directory (copyFile) +import System.Directory (createDirectoryIfMissing, copyFile) +import System.FilePath (takeDirectory) data ActionType = DryRun | CopyFiles @@ -12,4 +13,5 @@ getAction DryRun = putStrLn . show getAction CopyFiles = copy copy :: Copy -> IO () -copy (Copy from to) = copyFile from to +copy (Copy from to) = createDirectoryIfMissing True (takeDirectory to) >> + copyFile from to diff --git a/src/Args.hs b/src/Args.hs index 4a786f8..76bafe7 100644 --- a/src/Args.hs +++ b/src/Args.hs @@ -10,7 +10,7 @@ data Args = Args { source :: String , target :: String , attributes :: [Attribute] - , action :: ActionType + , actionType :: ActionType } deriving (Show, Eq) diff --git a/src/Channel.hs b/src/Channel.hs index 03da72b..2ef0a17 100644 --- a/src/Channel.hs +++ b/src/Channel.hs @@ -15,14 +15,15 @@ data Channel a = Channel (TVar Int) (TVar [a]) (TVar [a]) newChannel :: Int -> STM (Channel a) newChannel size = Channel <$> (newTVar size) <*> (newTVar []) <*> (newTVar []) -writeChan :: Channel a -> a -> STM () -writeChan (Channel size _read write) a = do +writeChan :: [a] -> Channel a -> STM () +writeChan as (Channel size _read write) = do + let count = length as avail <- readTVar size - if avail == 0 + if avail < count then retry - else writeTVar size (avail - 1) + else writeTVar size (avail - count) listend <- readTVar write - writeTVar write (a:listend) + writeTVar write (as ++ listend) readChan :: Channel a -> STM a readChan (Channel size read write) = do diff --git a/src/Itunes.hs b/src/Itunes.hs index 0f67f5e..cfb187f 100644 --- a/src/Itunes.hs +++ b/src/Itunes.hs @@ -1,4 +1,10 @@ -module Itunes where +module Itunes ( handleDirectory + , mkTransform + , Copy (Copy) + , Directory + , Transform + , Action + ) where import Control.Monad (filterM) import Data.List (foldl') diff --git a/stack.yaml b/stack.yaml index 078e19e..4ace414 100644 --- a/stack.yaml +++ b/stack.yaml @@ -46,6 +46,7 @@ extra-deps: [ , directory-1.3.3.1 , filepath-1.4.2 , stm-2.5.0.0 + , async-2.2.1 ] # Override default flag values for local packages and extra-deps