Skip to content

Instantly share code, notes, and snippets.

@ppelleti
Last active August 12, 2016 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ppelleti/c3ba8ee71cbe51f3d699 to your computer and use it in GitHub Desktop.
Save ppelleti/c3ba8ee71cbe51f3d699 to your computer and use it in GitHub Desktop.
copy photos from my phone using Android Debug Bridge
#!/usr/bin/env runhaskell
import Data.List
import System.Directory
import System.IO
import System.Process
import Data.Unicode.NormalizationInsensitive ( NI )
import qualified Data.Unicode.NormalizationInsensitive as NI
remoteDir = "/storage/extSdCard/DCIM/Camera"
localDir = "/Users/ppelleti/Pictures/Android"
getRemoteFiles :: String -> IO [String]
getRemoteFiles remoteDir = do
files <- readProcess "adb" ["shell", "ls", remoteDir] ""
return $ lines $ filter (/= '\r') files
getLocalFiles :: String -> IO [String]
getLocalFiles localDir = do
files <- getDirectoryContents localDir
return $ filter shouldKeep files
where shouldKeep ('.':_ ) = False
shouldKeep _ = True
copyOneFile :: String -> String -> IO ()
copyOneFile remoteFile localFile =
cmd ["adb", "pull", "-a", remoteFile, localFile]
cmd :: [String] -> IO ()
cmd (exe:args) = do
putStrLn $ unwords $ exe : map show args
callProcess exe args
copyFiles :: String -> String -> [String] -> IO ()
copyFiles rDir lDir files =
mapM_ cfile files
where cfile file = copyOneFile (rDir ++ "/" ++ file) (lDir ++ "/" ++ file)
copyNewFiles :: String -> String -> IO ()
copyNewFiles rDir lDir = do
rFiles <- map NI.mk <$> getRemoteFiles rDir
lFiles <- map NI.mk <$> getLocalFiles lDir
let files = rFiles \\ lFiles
copyFiles rDir lDir $ map NI.original files
main = copyNewFiles remoteDir localDir
-- Initial photos.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
-- The name of the package.
name: photos
-- The package version. See the Haskell package versioning policy (PVP)
-- for standards guiding when and how versions should be incremented.
-- http://www.haskell.org/haskellwiki/Package_versioning_policy
-- PVP summary: +-+------- breaking API changes
-- | | +----- non-breaking API additions
-- | | | +--- code changes with no API change
version: 0.1.0.0
-- A short (one-line) description of the package.
synopsis: copy photos from my phone using Android Debug Bridge
-- A longer description of the package.
-- description:
-- The license under which the package is released.
license: BSD3
-- The file containing the license text.
-- license-file: LICENSE
-- The package author(s).
author: Patrick Pelletier
-- An email address to which users can send suggestions, bug reports, and
-- patches.
maintainer: code@funwithsoftware.org
-- A copyright notice.
-- copyright:
-- category:
build-type: Simple
-- Extra files to be distributed with the package, such as examples or a
-- README.
-- extra-source-files:
-- Constraint on the version of Cabal needed to build this package.
cabal-version: >=1.10
executable android-photos
-- .hs or .lhs file containing the Main module.
main-is: android-photos.hs
-- Modules included in this executable, other than Main.
-- other-modules:
-- LANGUAGE extensions used by modules in this package.
-- other-extensions:
-- Other library packages from which modules are imported.
build-depends: base >=4 && <5
, directory
, process
, normalization-insensitive
-- Directories containing source files.
-- hs-source-dirs:
-- Base language which the package is written in.
default-language: Haskell2010
import Distribution.Simple
main = defaultMain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment