packages feed

breve 0.0.2.2 → 0.0.3.0

raw patch · 6 files changed

+107/−46 lines, 6 filesdep +directorydep +tconfigdep +xdg-basedir

Dependencies added: directory, tconfig, xdg-basedir

Files

README.md view
@@ -9,7 +9,7 @@  It was inspired by [hastebin](http://hastebin.com). -## Installing the app+## Installing  Install the app with cabal-install. Run @@ -21,7 +21,21 @@  The app will start serving on `http://localhost:3000`, listening on every active interface. -You can change the port and set a hostname via the `PORT` and `HOSTNAME` environment variables.+## Configure++You can change the options by editing the config file.+When you start the app an empty one will be created in:+`$XDG_CONFIG_HOME/breve` or `~/.config/breve` if unset.++The default values are:++```ini+hostname localhost+port     3000+urltable $XDG_CONFIG_HOME/breve+```++`urltable` is the location of breve url hashtable  ## License 
breve.cabal view
@@ -1,5 +1,5 @@ name:                breve-version:             0.0.2.2+version:             0.0.3.0 synopsis:            a url shortener description: @@ -29,10 +29,9 @@   other-modules:     Application, Breve.Common,                      Breve.Generator, Breve.UrlTable   other-extensions:  OverloadedStrings-  build-depends:     base ==4.*, simple >= 0.8.0,-                     wai ==2.*, wai-extra ==2.*, warp ==2.1.*,-                     aeson ==0.8.*, bytestring ==0.10.*,-                     transformers ==0.3.*, mtl ==2.1.*,-                     hashtables ==1.2.*, cryptohash ==0.11.*,-                     binary ==0.7.*, random ==1.1.*+  build-depends:     base ==4.*, simple >= 0.8.0, wai ==2.*, wai-extra ==2.*,+                     warp ==2.1.*, aeson ==0.8.*, bytestring ==0.10.*,+                     transformers ==0.3.*, mtl ==2.1.*, hashtables ==1.2.*,+                     cryptohash ==0.11.*, binary ==0.7.*, random ==1.1.*,+                     xdg-basedir ==0.2.*, tconfig ==0.5.*, directory ==1.2.*   ghc-options:       -threaded -O2
src/Application.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, RecordWildCards #-} module Application where  import Breve.Common@@ -21,17 +21,17 @@  app :: (Application -> IO ()) -> IO () app runner = do-  settings    <- newAppSettings-  (baseUrl,_) <- serverSettings-  table       <- records+  settings            <- newAppSettings+  ServerSettings {..} <- newServerSettings+  table               <- load urlTable -  cssPath   <- getDataFileName "layouts/main.css"-  indexPath <- getDataFileName "views/index.html"-  donePath  <- getDataFileName "views/done.html"+  css   <- getDataFileName "layouts/main.css"+  index <- getDataFileName "views/index.html"+  done  <- getDataFileName "views/done.html"    runner $ controllerApp settings $ do-    get "/" (render indexPath ())-    get "/main.css" (serveStatic cssPath)+    get "/" (render index ())+    get "/main.css" (serveStatic css)      get "/:word" $ do       word <- queryParam' "word"@@ -48,5 +48,5 @@         Just url -> do           word <- liftIO (insert table url)           logStr (printf "Registered %s -> %s " url word)-          render donePath $ object ["link" .= (baseUrl ++ word)]+          render done $ object ["link" .= (bindUrl ++ word)]         Nothing  -> respond badRequest
src/Breve/Common.hs view
@@ -1,32 +1,63 @@ {-# LANGUAGE MultiParamTypeClasses #-} module Breve.Common where -import Paths_breve            (getDataFileName)+import Paths_breve                     (getDataFileName)  import Control.Applicative-import Control.Monad.IO.Class (liftIO)-import Text.Printf            (printf)-import System.Environment     (lookupEnv)+import Control.Monad.IO.Class          (liftIO)+import Text.Printf                     (printf)+import System.Environment              (lookupEnv)+import System.Environment.XDG.BaseDir+import System.Directory                (doesFileExist)+import Data.TConfig  import Web.Simple.Templates import Network.Wai.Handler.Warp -data AppSettings = AppSettings { }--serverSettings :: IO (String, Settings)-serverSettings = do-  port <- maybe  3000       read <$> lookupEnv "PORT"-  host <- maybe "localhost" id   <$> lookupEnv "HOSTNAME"-  let opts = setPort port defaultSettings-      url  = if port == 80-             then printf "http://%s/"    host-             else printf "http://%s:%d/" host port-  return (url, opts)+data ServerSettings = ServerSettings+  { bindPort     :: Int+  , bindHostname :: String+  , bindUrl      :: String+  , urlTable     :: FilePath+  , warpSettings :: Settings+  } -newAppSettings :: IO AppSettings-newAppSettings = return AppSettings+data AppSettings = AppSettings {}  instance HasTemplates IO AppSettings where   defaultLayout = do     main <- liftIO (getDataFileName "layouts/main.html")     Just <$> getTemplate main+++newAppSettings :: IO AppSettings+newAppSettings = return AppSettings++createEmptyIfMissing :: FilePath -> IO FilePath+createEmptyIfMissing file = do+  exists <- doesFileExist file+  if not exists+    then writeFile file "" >> return file+    else return file++newServerSettings :: IO ServerSettings+newServerSettings = do+  urlsPath   <- getUserDataFile   "breve" ""+  configPath <- getUserConfigFile "breve" ""+  +  config <- readConfig =<< createEmptyIfMissing configPath+  let host = maybe "localhost" id   (getValue "hostname" config)+      port = maybe 3000        read (getValue "port"     config)+      urls = maybe urlsPath    id   (getValue "urltable" config)++  createEmptyIfMissing urls++  return ServerSettings+    { bindPort     = port+    , bindHostname = host+    , bindUrl      = if port == 80+                       then printf "http://%s/"    host+                       else printf "http://%s:%d/" host port+    , urlTable     = urls+    , warpSettings = setPort port defaultSettings+    }
src/Breve/UrlTable.hs view
@@ -1,24 +1,41 @@ module Breve.UrlTable ( UrlTable-, records+, load , insert , extract ) where  import Breve.Generator++import Control.Monad       (forever)+import Control.Concurrent  (forkIO, threadDelay)+import Text.Read           (readMaybe) import qualified Data.HashTable.IO as H  type UrlTable = H.CuckooHashTable Word Url ---Empty url hash table-records :: IO UrlTable-records = H.new+-- Periodically write a url table to a file+sync :: UrlTable -> FilePath -> IO ()+sync table file = forever $ do+  threadDelay (round 3.0e8)+  content <- fmap show (H.toList table)+  writeFile file content --- Insert the url in the table and return the word+-- Load a url table from a file+load :: FilePath -> IO UrlTable+load file = do+  content <- readFile file+  table <- case readMaybe content of+    Just list -> H.fromList list+    Nothing   -> H.new+  forkIO (sync table file)+  return table++-- Insert the url in a table and return the word insert :: UrlTable -> Url -> IO Word insert table url = H.insert table new url >> return new   where new = wordID url --- Lookup the table for the associated url+-- Lookup a table for the associated url extract :: UrlTable -> Word -> IO (Maybe Url) extract = H.lookup
src/Main.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, RecordWildCards #-}  import Application import Breve.Common@@ -9,6 +9,6 @@  main :: IO () main = do-  (url, settings) <- serverSettings-  putStrLn ("Serving on " ++ url)-  app (runSettings settings . logStdout)+  ServerSettings {..} <- newServerSettings+  putStrLn ("Serving on " ++ bindUrl)+  app (runSettings warpSettings . logStdout)