web: set up journal for yesod devel, store it in App (fixes #101)
The web app's journal state is now kept in the yesod App as an IORef, instead of using io-storage. yesod devel now works; it uses the journal file specified by $LEDGER_FILE, or ~/.hledger.journal. web: update journal state handling, fix yesod devel - WIP
This commit is contained in:
parent
c510f11424
commit
0df4a235af
@ -5,6 +5,7 @@ module Application
|
|||||||
, makeFoundation
|
, makeFoundation
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Data.IORef
|
||||||
import Import
|
import Import
|
||||||
import Yesod.Default.Config
|
import Yesod.Default.Config
|
||||||
import Yesod.Default.Main
|
import Yesod.Default.Main
|
||||||
@ -21,6 +22,10 @@ import Handler.JournalEntriesR
|
|||||||
import Handler.RegisterR
|
import Handler.RegisterR
|
||||||
|
|
||||||
import Hledger.Web.Options (defwebopts)
|
import Hledger.Web.Options (defwebopts)
|
||||||
|
import Hledger.Data (Journal, nulljournal)
|
||||||
|
import Hledger.Read (readJournalFile)
|
||||||
|
import Hledger.Utils (error')
|
||||||
|
import Hledger.Cli.Options (defcliopts, journalFilePathFromOpts)
|
||||||
|
|
||||||
-- This line actually creates our YesodDispatch instance. It is the second half
|
-- This line actually creates our YesodDispatch instance. It is the second half
|
||||||
-- of the call to mkYesodData which occurs in Foundation.hs. Please see the
|
-- of the call to mkYesodData which occurs in Foundation.hs. Please see the
|
||||||
@ -31,9 +36,10 @@ mkYesodDispatch "App" resourcesApp
|
|||||||
-- performs initialization and creates a WAI application. This is also the
|
-- performs initialization and creates a WAI application. This is also the
|
||||||
-- place to put your migrate statements to have automatic database
|
-- place to put your migrate statements to have automatic database
|
||||||
-- migrations handled by Yesod.
|
-- migrations handled by Yesod.
|
||||||
makeApplication :: AppConfig DefaultEnv Extra -> IO Application
|
makeApplication :: Journal -> AppConfig DefaultEnv Extra -> IO Application
|
||||||
makeApplication conf = do
|
makeApplication j conf = do
|
||||||
foundation <- makeFoundation conf
|
foundation <- makeFoundation conf
|
||||||
|
writeIORef (appJournal foundation) j
|
||||||
app <- toWaiAppPlain foundation
|
app <- toWaiAppPlain foundation
|
||||||
return $ logWare app
|
return $ logWare app
|
||||||
where
|
where
|
||||||
@ -44,13 +50,16 @@ makeFoundation :: AppConfig DefaultEnv Extra -> IO App
|
|||||||
makeFoundation conf = do
|
makeFoundation conf = do
|
||||||
manager <- newManager def
|
manager <- newManager def
|
||||||
s <- staticSite
|
s <- staticSite
|
||||||
return $ App conf s manager
|
jref <- newIORef nulljournal
|
||||||
defwebopts
|
return $ App conf s manager defwebopts jref
|
||||||
|
|
||||||
-- for yesod devel
|
-- for yesod devel
|
||||||
|
-- uses the journal specified by the LEDGER_FILE env var, or ~/.hledger.journal
|
||||||
getApplicationDev :: IO (Int, Application)
|
getApplicationDev :: IO (Int, Application)
|
||||||
getApplicationDev =
|
getApplicationDev = do
|
||||||
defaultDevelApp loader makeApplication
|
f <- journalFilePathFromOpts defcliopts
|
||||||
|
j <- either error' id `fmap` readJournalFile Nothing Nothing f
|
||||||
|
defaultDevelApp loader (makeApplication j)
|
||||||
where
|
where
|
||||||
loader = loadConfig (configSettings Development)
|
loader = loadConfig (configSettings Development)
|
||||||
{ csParseExtra = parseExtra
|
{ csParseExtra = parseExtra
|
||||||
|
|||||||
@ -7,6 +7,7 @@ See a default Yesod app's comments for more details of each part.
|
|||||||
module Foundation where
|
module Foundation where
|
||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
import Data.IORef
|
||||||
import Yesod
|
import Yesod
|
||||||
import Yesod.Static
|
import Yesod.Static
|
||||||
import Yesod.Default.Config
|
import Yesod.Default.Config
|
||||||
@ -26,6 +27,7 @@ import Web.ClientSession (getKey)
|
|||||||
import Text.Hamlet (hamletFile)
|
import Text.Hamlet (hamletFile)
|
||||||
|
|
||||||
import Hledger.Web.Options
|
import Hledger.Web.Options
|
||||||
|
import Hledger.Data.Types
|
||||||
-- import Hledger.Web.Settings
|
-- import Hledger.Web.Settings
|
||||||
-- import Hledger.Web.Settings.StaticFiles
|
-- import Hledger.Web.Settings.StaticFiles
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ data App = App
|
|||||||
, httpManager :: Manager
|
, httpManager :: Manager
|
||||||
--
|
--
|
||||||
, appOpts :: WebOpts
|
, appOpts :: WebOpts
|
||||||
|
, appJournal :: IORef Journal
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Set up i18n messages. See the message folder.
|
-- Set up i18n messages. See the message folder.
|
||||||
|
|||||||
@ -5,12 +5,13 @@ module Handler.Utils where
|
|||||||
import Prelude
|
import Prelude
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative ((<$>))
|
||||||
import Control.Monad.IO.Class (liftIO)
|
import Control.Monad.IO.Class (liftIO)
|
||||||
|
import Data.IORef
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text(pack,unpack)
|
import Data.Text(pack,unpack)
|
||||||
import Data.Time.Calendar
|
import Data.Time.Calendar
|
||||||
import Data.Time.Clock
|
import Data.Time.Clock
|
||||||
import Data.Time.Format
|
import Data.Time.Format
|
||||||
import System.IO.Storage (putValue, getValue)
|
-- import System.IO.Storage (putValue, getValue)
|
||||||
import System.Locale (defaultTimeLocale)
|
import System.Locale (defaultTimeLocale)
|
||||||
#if BLAZE_HTML_0_5
|
#if BLAZE_HTML_0_5
|
||||||
import Text.Blaze.Html (toHtml)
|
import Text.Blaze.Html (toHtml)
|
||||||
@ -70,7 +71,7 @@ getViewData :: Handler ViewData
|
|||||||
getViewData = do
|
getViewData = do
|
||||||
app <- getYesod
|
app <- getYesod
|
||||||
let opts@WebOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} = appOpts app
|
let opts@WebOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} = appOpts app
|
||||||
(j, err) <- getCurrentJournal $ copts{reportopts_=ropts{no_elide_=True}}
|
(j, err) <- getCurrentJournal app copts{reportopts_=ropts{no_elide_=True}}
|
||||||
msg <- getMessageOr err
|
msg <- getMessageOr err
|
||||||
Just here <- getCurrentRoute
|
Just here <- getCurrentRoute
|
||||||
today <- liftIO getCurrentDay
|
today <- liftIO getCurrentDay
|
||||||
@ -88,17 +89,18 @@ getViewData = do
|
|||||||
-- | Update our copy of the journal if the file changed. If there is an
|
-- | Update our copy of the journal if the file changed. If there is an
|
||||||
-- error while reloading, keep the old one and return the error, and set a
|
-- error while reloading, keep the old one and return the error, and set a
|
||||||
-- ui message.
|
-- ui message.
|
||||||
getCurrentJournal :: CliOpts -> Handler (Journal, Maybe String)
|
getCurrentJournal :: App -> CliOpts -> Handler (Journal, Maybe String)
|
||||||
getCurrentJournal opts = do
|
getCurrentJournal app opts = do
|
||||||
j <- liftIO $ fromJust `fmap` getValue "hledger" "journal"
|
-- XXX put this inside atomicModifyIORef' for thread safety
|
||||||
|
j <- liftIO $ readIORef $ appJournal app
|
||||||
(jE, changed) <- liftIO $ journalReloadIfChanged opts j
|
(jE, changed) <- liftIO $ journalReloadIfChanged opts j
|
||||||
if not changed
|
if not changed
|
||||||
then return (j,Nothing)
|
then return (j,Nothing)
|
||||||
else case jE of
|
else case jE of
|
||||||
Right j' -> do liftIO $ putValue "hledger" "journal" j'
|
Right j' -> do liftIO $ writeIORef (appJournal app) j'
|
||||||
return (j',Nothing)
|
return (j',Nothing)
|
||||||
Left e -> do setMessage $ "error while reading" {- ++ ": " ++ e-}
|
Left e -> do setMessage $ "error while reading" {- ++ ": " ++ e-}
|
||||||
return (j, Just e)
|
return (j, Just e)
|
||||||
|
|
||||||
-- | Get the named request parameter, or the empty string if not present.
|
-- | Get the named request parameter, or the empty string if not present.
|
||||||
getParameterOrNull :: String -> Handler String
|
getParameterOrNull :: String -> Handler String
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import Prelude hiding (putStrLn)
|
|||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
import Data.Text (pack)
|
import Data.Text (pack)
|
||||||
import System.Exit (exitSuccess)
|
import System.Exit (exitSuccess)
|
||||||
import System.IO.Storage (withStore, putValue)
|
-- import System.IO.Storage (withStore, putValue)
|
||||||
import Text.Printf
|
import Text.Printf
|
||||||
|
|
||||||
import Hledger
|
import Hledger
|
||||||
@ -67,18 +67,8 @@ web opts j = do
|
|||||||
|
|
||||||
server :: String -> Int -> WebOpts -> Journal -> IO ()
|
server :: String -> Int -> WebOpts -> Journal -> IO ()
|
||||||
server baseurl port opts j = do
|
server baseurl port opts j = do
|
||||||
_ <- printf "Starting http server on port %d with base url %s\n" port baseurl
|
_ <- printf "Starting http server on port %d with base url %s\n" port baseurl
|
||||||
-- let a = App{getStatic=static staticdir
|
app <- makeApplication j (AppConfig {
|
||||||
-- ,appRoot=pack baseurl
|
|
||||||
-- ,appOpts=opts
|
|
||||||
-- ,appArgs=patterns_ $ reportopts_ $ cliopts_ opts
|
|
||||||
-- ,appJournal=j
|
|
||||||
-- }
|
|
||||||
withStore "hledger" $ do
|
|
||||||
putValue "hledger" "journal" j
|
|
||||||
|
|
||||||
-- defaultMain (fromArgs parseExtra) makeApplication
|
|
||||||
app <- makeApplication (AppConfig {
|
|
||||||
appEnv = Development
|
appEnv = Development
|
||||||
, appPort = port_ opts
|
, appPort = port_ opts
|
||||||
, appRoot = pack baseurl
|
, appRoot = pack baseurl
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
import Distribution.Simple
|
|
||||||
main = defaultMain
|
|
||||||
@ -6,17 +6,12 @@ import Control.Concurrent (forkIO)
|
|||||||
import System.Directory (doesFileExist, removeFile)
|
import System.Directory (doesFileExist, removeFile)
|
||||||
import System.Exit (exitSuccess)
|
import System.Exit (exitSuccess)
|
||||||
import Control.Concurrent (threadDelay)
|
import Control.Concurrent (threadDelay)
|
||||||
import System.IO.Storage (withStore, putValue)
|
|
||||||
|
|
||||||
import Hledger (readJournalFile)
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
putStrLn "Starting devel application"
|
putStrLn "Starting devel application"
|
||||||
(port, app) <- getApplicationDev
|
(port, app) <- getApplicationDev
|
||||||
forkIO $
|
forkIO $
|
||||||
withStore "hledger" $ do
|
|
||||||
readJournalFile Nothing Nothing "dev.journal" >>= putValue "hledger" "journal"
|
|
||||||
runSettings defaultSettings
|
runSettings defaultSettings
|
||||||
{ settingsPort = port
|
{ settingsPort = port
|
||||||
} app
|
} app
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user