dropping imegamagick for juicypixels
This commit is contained in:
parent
eaa80952a6
commit
dce81ef161
3 changed files with 79 additions and 54 deletions
|
@ -24,10 +24,11 @@ import qualified Data.Text as T
|
||||||
import Data.List as L
|
import Data.List as L
|
||||||
import qualified System.FilePath as FP
|
import qualified System.FilePath as FP
|
||||||
import System.Directory
|
import System.Directory
|
||||||
import Filesystem.Path.CurrentOS
|
|
||||||
import Graphics.ImageMagick.MagickWand
|
|
||||||
import Text.Blaze.Internal
|
import Text.Blaze.Internal
|
||||||
import Codec.ImageType
|
import Codec.ImageType
|
||||||
|
import Codec.Picture
|
||||||
|
import Codec.Picture.Metadata as PM
|
||||||
|
import Codec.Picture.ScaleDCT
|
||||||
|
|
||||||
getDirectUploadR :: AlbumId -> Handler Html
|
getDirectUploadR :: AlbumId -> Handler Html
|
||||||
getDirectUploadR albumId = do
|
getDirectUploadR albumId = do
|
||||||
|
@ -84,12 +85,11 @@ postDirectUploadR albumId = do
|
||||||
isOk <- liftIO $ checkCVE_2016_3714 path mime
|
isOk <- liftIO $ checkCVE_2016_3714 path mime
|
||||||
if isOk
|
if isOk
|
||||||
then do
|
then do
|
||||||
(thumbPath, prevPath, iWidth, tWidth, pWidth) <- generateThumb path ownerId albumId
|
meta <- generateThumbs path ownerId albumId
|
||||||
tempName <- if
|
tempName <- if length indFils == 1
|
||||||
length indFils == 1
|
|
||||||
then return $ fileBulkPrefix temp
|
then return $ fileBulkPrefix temp
|
||||||
else return (fileBulkPrefix temp `T.append` " " `T.append` T.pack (show (index :: Int)) `T.append` " of " `T.append` T.pack (show (length indFils)))
|
else return (fileBulkPrefix temp `T.append` " " `T.append` T.pack (show (index :: Int)) `T.append` " of " `T.append` T.pack (show (length indFils)))
|
||||||
let medium = Medium tempName ('/' : path) ('/' : thumbPath) mime (fileBulkTime temp) (fileBulkOwner temp) (fileBulkDesc temp) (fileBulkTags temp) iWidth tWidth albumId ('/' : prevPath) pWidth
|
let medium = Medium tempName ('/' : path) ('/' : metaThumbPath meta) mime (fileBulkTime temp) (fileBulkOwner temp) (fileBulkDesc temp) (fileBulkTags temp) (metaImageWidth meta) (metaThumbWidth meta) albumId ('/' : metaPreviewPath meta) (metaPreviewWidth meta)
|
||||||
mId <- runDB $ I.insert medium
|
mId <- runDB $ I.insert medium
|
||||||
inALbum <- runDB $ getJust albumId
|
inALbum <- runDB $ getJust albumId
|
||||||
let newMediaList = mId : albumContent inALbum
|
let newMediaList = mId : albumContent inALbum
|
||||||
|
@ -126,39 +126,50 @@ postDirectUploadR albumId = do
|
||||||
setMessage "This Album does not exist"
|
setMessage "This Album does not exist"
|
||||||
redirect $ AlbumR albumId
|
redirect $ AlbumR albumId
|
||||||
|
|
||||||
generateThumb
|
-- | Type to pass metadata about imgaes around.
|
||||||
:: FP.FilePath
|
data ThumbsMeta = ThumbsMeta
|
||||||
-> UserId
|
{ metaThumbPath :: FP.FilePath -- ^ Filepath of the new thumbnail image
|
||||||
-> AlbumId
|
, metaPreviewPath :: FP.FilePath -- ^ Filepath of the new preview image
|
||||||
-> Handler (FP.FilePath, FP.FilePath, Int, Int, Int)
|
, metaImageWidth :: Int -- ^ Width of the original image
|
||||||
generateThumb path userId albumId = do
|
, metaThumbWidth :: Int -- ^ Width of the generated thumbnail image
|
||||||
let newName = FP.takeBaseName path ++ "_thumb.jpg"
|
, metaPreviewWidth :: Int -- ^ Width of the generated preview image
|
||||||
let newPath = "static" FP.</> "data" FP.</> T.unpack (extractKey userId) FP.</> T.unpack (extractKey albumId) FP.</> newName
|
}
|
||||||
let prevName = FP.takeBaseName path ++ "_preview.jpg"
|
|
||||||
let prevPath = "static" FP.</> "data" FP.</> T.unpack (extractKey userId) FP.</> T.unpack (extractKey albumId) FP.</> prevName
|
-- | generate thumbnail and preview images from uploaded image
|
||||||
(iWidth, tWidth, pWidth) <- liftIO $ withMagickWandGenesis $ do
|
generateThumbs
|
||||||
(_, w) <- magickWand
|
:: FP.FilePath -- ^ Path to original image
|
||||||
(_, p) <- magickWand
|
-> UserId -- ^ Uploading user
|
||||||
readImage w (T.pack path)
|
-> AlbumId -- ^ Destination album
|
||||||
readImage p (T.pack path)
|
-> Handler ThumbsMeta -- ^ Resulting metadata to store
|
||||||
w1 <- getImageWidth w
|
generateThumbs path uId aId = do
|
||||||
h1 <- getImageHeight w
|
eimg <- liftIO $ readImageWithMetadata path
|
||||||
let h2 = 230
|
case eimg of
|
||||||
let w2 = floor (fromIntegral w1 / fromIntegral h1 * fromIntegral h2 :: Double)
|
Left e -> error e
|
||||||
let w3 = 1380
|
Right (orig, meta) -> do
|
||||||
let h3 = floor (fromIntegral h1 / fromIntegral w1 * fromIntegral w3 :: Double)
|
let thumbName = FP.takeBaseName path ++ "_thumb.jpg"
|
||||||
setImageAlphaChannel w deactivateAlphaChannel
|
prevName = FP.takeBaseName path ++ "_preview.jpg"
|
||||||
setImageAlphaChannel p deactivateAlphaChannel
|
pathPrefix = "static" FP.</> "data" FP.</> T.unpack (extractKey uId) FP.</> T.unpack (extractKey aId)
|
||||||
setImageFormat w "jpeg"
|
tPath = pathPrefix FP.</> thumbName
|
||||||
setImageFormat p "jpeg"
|
pPath = pathPrefix FP.</> prevName
|
||||||
resizeImage w w2 h2 lanczosFilter 1
|
origPix = convertRGBA8 orig
|
||||||
resizeImage p w3 h3 lanczosFilter 1
|
oWidth = fromIntegral $ fromJust $ PM.lookup Width meta :: Int
|
||||||
setImageCompressionQuality w 95
|
oHeight = fromIntegral $ fromJust $ PM.lookup Height meta :: Int
|
||||||
setImageCompressionQuality p 95
|
tWidth = floor (fromIntegral oWidth / fromIntegral oHeight * fromIntegral tHeight :: Double)
|
||||||
writeImage w (Just (T.pack newPath))
|
tHeight = 230 :: Int
|
||||||
writeImage p (Just (T.pack prevPath))
|
pWidth = 1380 :: Int
|
||||||
return (w1, w2, w3)
|
pScale = (fromIntegral pWidth :: Double) / (fromIntegral oWidth :: Double)
|
||||||
return (newPath, prevPath, iWidth, tWidth, pWidth)
|
pHeight = floor (fromIntegral oHeight * pScale)
|
||||||
|
tPix = scale (tWidth, tHeight) origPix
|
||||||
|
pPix = scale (pWidth, pHeight) origPix
|
||||||
|
liftIO $ saveJpgImage 95 tPath $ ImageRGBA8 tPix
|
||||||
|
liftIO $ saveJpgImage 95 pPath $ ImageRGBA8 pPix
|
||||||
|
return $ ThumbsMeta
|
||||||
|
{ metaThumbPath = tPath
|
||||||
|
, metaPreviewPath = pPath
|
||||||
|
, metaImageWidth = oWidth
|
||||||
|
, metaThumbWidth = tWidth
|
||||||
|
, metaPreviewWidth = pWidth
|
||||||
|
}
|
||||||
|
|
||||||
checkCVE_2016_3714 :: FP.FilePath -> Text -> IO Bool
|
checkCVE_2016_3714 :: FP.FilePath -> Text -> IO Bool
|
||||||
checkCVE_2016_3714 p m =
|
checkCVE_2016_3714 p m =
|
||||||
|
@ -273,12 +284,18 @@ postUploadR = do
|
||||||
isOk <- liftIO $ checkCVE_2016_3714 path mime
|
isOk <- liftIO $ checkCVE_2016_3714 path mime
|
||||||
if isOk
|
if isOk
|
||||||
then do
|
then do
|
||||||
(thumbPath, prevPath, iWidth, tWidth, pWidth) <- generateThumb path ownerId inAlbumId
|
meta <- generateThumbs path ownerId inAlbumId
|
||||||
tempName <- if
|
tempName <- if
|
||||||
length indFils == 1
|
length indFils == 1
|
||||||
then return $ fileBulkPrefix temp
|
then return $ fileBulkPrefix temp
|
||||||
else return (fileBulkPrefix temp `T.append` " " `T.append` T.pack (show (index :: Int)) `T.append` " of " `T.append` T.pack (show (length indFils)))
|
else
|
||||||
let medium = Medium tempName ('/' : path) ('/' : thumbPath) mime (fileBulkTime temp) (fileBulkOwner temp) (fileBulkDesc temp) (fileBulkTags temp) iWidth tWidth inAlbumId ('/' : prevPath) pWidth
|
return
|
||||||
|
(fileBulkPrefix temp `T.append`
|
||||||
|
" " `T.append`
|
||||||
|
T.pack (show (index :: Int)) `T.append`
|
||||||
|
" of " `T.append`
|
||||||
|
T.pack (show (length indFils)))
|
||||||
|
let medium = Medium tempName ('/' : path) ('/' : metaThumbPath meta) mime (fileBulkTime temp) (fileBulkOwner temp) (fileBulkDesc temp) (fileBulkTags temp) (metaImageWidth meta) (metaThumbWidth meta) inAlbumId ('/' : metaPreviewPath meta) (metaPreviewWidth meta)
|
||||||
mId <- runDB $ I.insert medium
|
mId <- runDB $ I.insert medium
|
||||||
inALbum <- runDB $ getJust inAlbumId
|
inALbum <- runDB $ getJust inAlbumId
|
||||||
let newMediaList = mId : albumContent inALbum
|
let newMediaList = mId : albumContent inALbum
|
||||||
|
|
|
@ -118,6 +118,8 @@ library
|
||||||
, bloodhound >= 0.8
|
, bloodhound >= 0.8
|
||||||
, http-types
|
, http-types
|
||||||
, image-type
|
, image-type
|
||||||
|
, JuicyPixels >= 3.2.7
|
||||||
|
, JuicyPixels-scale-dct
|
||||||
-- for Migrations
|
-- for Migrations
|
||||||
, HDBC
|
, HDBC
|
||||||
, HDBC-postgresql
|
, HDBC-postgresql
|
||||||
|
|
30
stack.yaml
30
stack.yaml
|
@ -8,7 +8,8 @@ extra-deps:
|
||||||
- HDBC-postgresql-2.3.2.3
|
- HDBC-postgresql-2.3.2.3
|
||||||
- HTTP-4000.2.23
|
- HTTP-4000.2.23
|
||||||
- HUnit-1.3.1.1
|
- HUnit-1.3.1.1
|
||||||
- JuicyPixels-3.2.6.4
|
- JuicyPixels-3.2.7
|
||||||
|
- JuicyPixels-scale-dct-0.1.1.0
|
||||||
- MonadCatchIO-transformers-0.3.1.3
|
- MonadCatchIO-transformers-0.3.1.3
|
||||||
- QuickCheck-2.8.2
|
- QuickCheck-2.8.2
|
||||||
- ReadArgs-1.2.2
|
- ReadArgs-1.2.2
|
||||||
|
@ -28,7 +29,8 @@ extra-deps:
|
||||||
- attoparsec-0.13.0.1
|
- attoparsec-0.13.0.1
|
||||||
- authenticate-1.3.2.11
|
- authenticate-1.3.2.11
|
||||||
- auto-update-0.1.3
|
- auto-update-0.1.3
|
||||||
- base-orphans-0.5.1
|
- base-compat-0.9.0
|
||||||
|
- base-orphans-0.5.3
|
||||||
- base16-bytestring-0.1.1.6
|
- base16-bytestring-0.1.1.6
|
||||||
- base64-bytestring-1.0.0.1
|
- base64-bytestring-1.0.0.1
|
||||||
- basic-prelude-0.5.0
|
- basic-prelude-0.5.0
|
||||||
|
@ -40,6 +42,7 @@ extra-deps:
|
||||||
- byteable-0.1.1
|
- byteable-0.1.1
|
||||||
- byteorder-1.0.4
|
- byteorder-1.0.4
|
||||||
- bytestring-builder-0.10.6.0.0
|
- bytestring-builder-0.10.6.0.0
|
||||||
|
- carray-0.1.6.3
|
||||||
- case-insensitive-1.2.0.5
|
- case-insensitive-1.2.0.5
|
||||||
- cereal-0.5.1.0
|
- cereal-0.5.1.0
|
||||||
- chunked-data-0.2.0
|
- chunked-data-0.2.0
|
||||||
|
@ -53,7 +56,7 @@ extra-deps:
|
||||||
- comonad-4.2.7.2
|
- comonad-4.2.7.2
|
||||||
- conduit-1.2.6.1
|
- conduit-1.2.6.1
|
||||||
- conduit-combinators-1.0.3
|
- conduit-combinators-1.0.3
|
||||||
- conduit-extra-1.1.9.2
|
- conduit-extra-1.1.13.1
|
||||||
- connection-0.2.5
|
- connection-0.2.5
|
||||||
- contravariant-1.3.3
|
- contravariant-1.3.3
|
||||||
- convertible-1.1.1.0
|
- convertible-1.1.1.0
|
||||||
|
@ -85,6 +88,7 @@ extra-deps:
|
||||||
- exceptions-0.8.0.2
|
- exceptions-0.8.0.2
|
||||||
- extensible-exceptions-0.1.1.4
|
- extensible-exceptions-0.1.1.4
|
||||||
- fast-logger-2.4.1
|
- fast-logger-2.4.1
|
||||||
|
- fft-0.1.8.3
|
||||||
- file-embed-0.0.9
|
- file-embed-0.0.9
|
||||||
- filemanip-0.3.6.3
|
- filemanip-0.3.6.3
|
||||||
- free-4.12.1
|
- free-4.12.1
|
||||||
|
@ -95,9 +99,9 @@ extra-deps:
|
||||||
- hjsmin-0.1.5.1
|
- hjsmin-0.1.5.1
|
||||||
- hourglass-0.2.9
|
- hourglass-0.2.9
|
||||||
- hslua-0.4.1
|
- hslua-0.4.1
|
||||||
- hspec-2.2.2
|
- hspec-2.2.3
|
||||||
- hspec-core-2.2.2
|
- hspec-core-2.2.3
|
||||||
- hspec-discover-2.2.2
|
- hspec-discover-2.2.3
|
||||||
- hspec-expectations-0.7.2
|
- hspec-expectations-0.7.2
|
||||||
- html-conduit-1.2.1
|
- html-conduit-1.2.1
|
||||||
- http-api-data-0.2.2
|
- http-api-data-0.2.2
|
||||||
|
@ -110,6 +114,7 @@ extra-deps:
|
||||||
- image-type-0.1.0.0
|
- image-type-0.1.0.0
|
||||||
- imagemagick-0.0.4.1
|
- imagemagick-0.0.4.1
|
||||||
- iproute-1.7.0
|
- iproute-1.7.0
|
||||||
|
- ix-shapable-0.1.0
|
||||||
- kan-extensions-4.2.3
|
- kan-extensions-4.2.3
|
||||||
- keys-3.10.2
|
- keys-3.10.2
|
||||||
- language-javascript-0.5.14.2
|
- language-javascript-0.5.14.2
|
||||||
|
@ -122,7 +127,7 @@ extra-deps:
|
||||||
- monad-logger-0.3.16
|
- monad-logger-0.3.16
|
||||||
- monad-loops-0.4.3
|
- monad-loops-0.4.3
|
||||||
- monads-tf-0.1.0.2
|
- monads-tf-0.1.0.2
|
||||||
- mono-traversable-0.10.1
|
- mono-traversable-0.10.1.1
|
||||||
- mtl-2.2.1
|
- mtl-2.2.1
|
||||||
- mtl-compat-0.2.1.3
|
- mtl-compat-0.2.1.3
|
||||||
- mutable-containers-0.3.2
|
- mutable-containers-0.3.2
|
||||||
|
@ -138,10 +143,10 @@ extra-deps:
|
||||||
- parsec-3.1.9
|
- parsec-3.1.9
|
||||||
- path-pieces-0.2.1
|
- path-pieces-0.2.1
|
||||||
- pem-0.2.2
|
- pem-0.2.2
|
||||||
- persistent-2.2.4
|
- persistent-2.2.4.1
|
||||||
- persistent-postgresql-2.2.2
|
- persistent-postgresql-2.2.2
|
||||||
- persistent-sqlite-2.2
|
- persistent-sqlite-2.2.1
|
||||||
- persistent-template-2.1.5
|
- persistent-template-2.1.6
|
||||||
- pointed-4.2.0.2
|
- pointed-4.2.0.2
|
||||||
- postgresql-libpq-0.9.1.1
|
- postgresql-libpq-0.9.1.1
|
||||||
- postgresql-simple-0.5.1.2
|
- postgresql-simple-0.5.1.2
|
||||||
|
@ -169,6 +174,7 @@ extra-deps:
|
||||||
- split-0.2.2
|
- split-0.2.2
|
||||||
- stm-2.4.4.1
|
- stm-2.4.4.1
|
||||||
- stm-chans-3.0.0.4
|
- stm-chans-3.0.0.4
|
||||||
|
- storable-complex-0.2.2
|
||||||
- streaming-commons-0.1.15
|
- streaming-commons-0.1.15
|
||||||
- stringsearch-0.3.6.6
|
- stringsearch-0.3.6.6
|
||||||
- syb-0.6
|
- syb-0.6
|
||||||
|
@ -177,7 +183,7 @@ extra-deps:
|
||||||
- tagsoup-0.13.6
|
- tagsoup-0.13.6
|
||||||
- tagstream-conduit-0.5.5.3
|
- tagstream-conduit-0.5.5.3
|
||||||
- temporary-1.2.0.3
|
- temporary-1.2.0.3
|
||||||
- texmath-0.8.4.1
|
- texmath-0.8.6.1
|
||||||
- text-1.2.2.0
|
- text-1.2.2.0
|
||||||
- tf-random-0.5
|
- tf-random-0.5
|
||||||
- time-locale-compat-0.1.1.1
|
- time-locale-compat-0.1.1.1
|
||||||
|
@ -196,7 +202,7 @@ extra-deps:
|
||||||
- void-0.7.1
|
- void-0.7.1
|
||||||
- wai-3.0.5.0
|
- wai-3.0.5.0
|
||||||
- wai-app-static-3.1.4.1
|
- wai-app-static-3.1.4.1
|
||||||
- wai-extra-3.0.14
|
- wai-extra-3.0.15
|
||||||
- wai-logger-2.2.4.1
|
- wai-logger-2.2.4.1
|
||||||
- warp-3.1.12
|
- warp-3.1.12
|
||||||
- word8-0.1.2
|
- word8-0.1.2
|
||||||
|
|
Loading…
Reference in a new issue