photoname 2.2 → 2.3.0
raw patch · 12 files changed
+76/−58 lines, 12 files
Files
- LICENSE +1/−1
- doc/hcar-photoname +0/−26
- doc/hcar-photoname.tex +21/−0
- photoname.cabal +2/−2
- src/Photoname/Date.hs +1/−1
- src/Photoname/Opts.hs +2/−2
- src/Photoname/Serial.hs +2/−2
- src/photoname.hs +41/−16
- testsuite/TestHelp.hs +1/−1
- testsuite/TestLink.hs +3/−5
- testsuite/Util.hs +1/−1
- testsuite/runtests.hs +1/−1
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2007-2009 Dino Morelli+Copyright (c) 2007-2010 Dino Morelli All rights reserved. Redistribution and use in source and binary forms, with or without
− doc/hcar-photoname
@@ -1,26 +0,0 @@-This information is for this project's entry in the _Haskell Communities and Activities Report_ (http://www.haskell.org/communities/)--entry begins below-------------[section 6 Applications]--6.x photoname--------Report by: Dino Morelli-Maintainer: Dino Morelli-Status: stable, maintained--------photoname is a command-line utility for renaming/moving photo image files. The new folder location and naming are determined by the EXIF photo shoot date and the usually-camera-assigned serial number, often appearing in the filename.--Between versions 2.0 and 2.1 the software is largely the same on the outside but has undergone extensive changes inside. Most of this involving redesign with monad transformers.--photoname is on Hackage and can be acquired using darcs or other methods. See the project page below for more.---Further reading-- * Project page: http://ui3.info/d/proj/photoname.html- * Source repository: darcs get http://ui3.info/darcs/photoname
+ doc/hcar-photoname.tex view
@@ -0,0 +1,21 @@+\begin{hcarentry}{photoname}+\label{photoname}+\report{Dino Morelli}%11/08+\status{stable, maintained}+\makeheader++photoname is a command-line utility for renaming/moving photo image files. The new folder location and naming are determined by the EXIF photo shoot date and the usually-camera-assigned serial number, often appearing in the filename.++photoname is on Hackage and can be acquired using darcs or other methods. See the project page below for more.++\FurtherReading+\begin{compactitem}+\item Project page:++\url{http://ui3.info/d/proj/photoname.html}++\item Source repository:++\texttt{darcs get} \url{http://ui3.info/darcs/photoname}+\end{compactitem}+\end{hcarentry}
photoname.cabal view
@@ -1,10 +1,10 @@ name: photoname cabal-version: >= 1.2-version: 2.2+version: 2.3.0 build-type: Simple license: BSD3 license-file: LICENSE-copyright: 2007-2009 Dino Morelli +copyright: 2007-2010 Dino Morelli author: Dino Morelli maintainer: Dino Morelli <dino@ui3.info> stability: stable
src/Photoname/Date.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info>
src/Photoname/Opts.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info> @@ -79,5 +79,5 @@ , "" , "Note that the default behavior of this software is to create hard links to the new paths and leave the original links as they were. You can use the --move switch to blow away the original location, leaving only the new." , ""- , "Version 2.2 2009-Jun-07 Dino Morelli <dino@ui3.info>"+ , "Version 2.3.0 2010-Jan-17 Dino Morelli <dino@ui3.info>" ]
src/Photoname/Serial.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info> @@ -39,5 +39,5 @@ getSerial :: (MonadError String m) => String -> m String getSerial path = case (parse serialNum "" path) of- Left _ -> throwError $ "File " ++ path ++ " has no serial"+ Left _ -> throwError "has no serial" Right serial -> return serial
src/photoname.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info> @@ -6,9 +6,10 @@ import Control.Monad.Error import Control.Monad.Reader-import Graphics.Exif ( fromFile, getTag )+import Graphics.Exif ( fromFile, getTag, Exif ) import System.Environment ( getArgs ) import System.FilePath+import System.IO.Error import System.Posix import Photoname.Date@@ -29,25 +30,45 @@ groupExecuteMode +{- load Exif information from a filename, returning Nothing if libexif+ encounters a NULL instead of raising an IO error.++ This is somewhat bogus because of the error type that is used by+ the EXIF library. We have to compare the error string to see if it+ is the kind of user error that we expect. If we build against an+ EXIF library that raises some other exception, then this build will+ still succeed, and the exception will be propagated instead of+ transformed into a handled photoname error.+-}+safeExif :: FilePath -> IO (Maybe Exif)+safeExif = try . fromFile >=> either handleBadExif (return . Just)+ where+ isBadExif e =+ ioeGetErrorString e == "mkExif: NULL" && isUserError e+ handleBadExif e =+ if isBadExif e then return Nothing else ioError e++ {- Get shoot date from the exif information. There are several tags potentially containing dates. Try them in a specific order until we find one that has data. -} getDate :: (MonadError String m, MonadIO m) => FilePath -> m String-getDate path = do- exif <- liftIO $ fromFile path+getDate = loadExif >=> getOneOf dateTagNames+ where+ loadExif = (liftIO . safeExif) >=>+ maybe (throwError "failed EXIF loading") return - -- This foldl gets us the first IO (Maybe String) that's not Nothing- maybeDate <- liftIO $ foldl (liftM2 mplus) (return Nothing) $- map (getTag exif)- ["DateTimeDigitized", "DateTimeOriginal", "DateTime"]+ getOneOf [] _ = throwError "has no EXIF date"+ getOneOf (tagName:tagNames) exif =+ maybe (getOneOf tagNames exif) return =<<+ liftIO (getTag exif tagName) - case maybeDate of- Just d -> return d- Nothing -> throwError $ "File " ++ path ++ " has no EXIF date"+ dateTagNames =+ ["DateTimeDigitized", "DateTimeOriginal", "DateTime"] -{- Take a file path to a JPEG file and use EXIF information available to +{- Take a file path to a JPEG file and use EXIF information available to move the file to a new location below the given basedir. -} createNewLink :: FilePath -> FilePath -> Ph ()@@ -58,11 +79,10 @@ -- Check for existance of the target file exists <- liftIO $ fileExist newPath- when exists $ throwError $- "** " ++ oldPath ++ " -> " ++ newPath ++ " exists!"+ when exists $ throwError $ "Destination " ++ newPath ++ " exists!" -- Display what will be done- unless (optQuiet opts) $ + unless (optQuiet opts) $ liftIO $ putStrLn $ oldPath ++ " -> " ++ newPath unless (optNoAction opts) $ do@@ -78,8 +98,10 @@ return () + let errPrefix = "** Processing " ++ oldPath ++ ": "+ case result of- Left errMsg -> liftIO $ putStrLn errMsg+ Left errMsg -> liftIO $ putStrLn $ errPrefix ++ errMsg Right _ -> return () @@ -134,6 +156,9 @@ -- User gave no files at all. Display help executeCommands [] = liftIO $ putStrLn usageText++-- User gave just a dir and no files at all. Display help+executeCommands [_] = liftIO $ putStrLn usageText -- Normal program operation, process the files with the args. executeCommands (dir:filePaths) = do
testsuite/TestHelp.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info>
testsuite/TestLink.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info> @@ -159,8 +159,7 @@ -- Test output to stdout assertBool "no EXIF: correct output"- (output =~ "File testsuite/resources/noExif.jpg has no EXIF date"- :: Bool)+ (output =~ "\\*\\* Processing testsuite/resources/noExif.jpg: failed EXIF loading" :: Bool) testNoSerial :: Test@@ -172,8 +171,7 @@ -- Test output to stdout assertBool "no serial in filename: correct output"- (output =~ "File testsuite/resources/noSerial.jpg has no serial"- :: Bool)+ (output =~ "\\*\\* Processing testsuite/resources/noSerial.jpg: has no serial" :: Bool) testDirForFile :: Test
testsuite/Util.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info>
testsuite/runtests.hs view
@@ -1,4 +1,4 @@--- Copyright: 2007-2009 Dino Morelli+-- Copyright: 2007-2010 Dino Morelli -- License: BSD3 (see LICENSE) -- Author: Dino Morelli <dino@ui3.info>