forked from GitHub/gf-core
Add cloud services needed by gfse to "gf -server" mode
This commit is contained in:
@@ -7,8 +7,10 @@ import System.IO(stdout,stderr)
|
|||||||
import System.IO.Error(try,ioError)
|
import System.IO.Error(try,ioError)
|
||||||
import System.Directory(doesDirectoryExist,doesFileExist,createDirectory,
|
import System.Directory(doesDirectoryExist,doesFileExist,createDirectory,
|
||||||
setCurrentDirectory,getCurrentDirectory,
|
setCurrentDirectory,getCurrentDirectory,
|
||||||
getDirectoryContents)
|
getDirectoryContents,removeFile,removeDirectory)
|
||||||
import System.FilePath(takeExtension,takeFileName,takeDirectory,(</>))
|
import System.FilePath(takeExtension,takeFileName,takeDirectory,(</>))
|
||||||
|
import System.Posix.Files(getFileStatus,isSymbolicLink,removeLink,
|
||||||
|
createSymbolicLink)
|
||||||
import Control.Concurrent.MVar(newMVar,modifyMVar)
|
import Control.Concurrent.MVar(newMVar,modifyMVar)
|
||||||
import Network.URI(URI(..))
|
import Network.URI(URI(..))
|
||||||
import Network.Shed.Httpd(initServer,Request(..),Response(..),queryToArguments,
|
import Network.Shed.Httpd(initServer,Request(..),Response(..),queryToArguments,
|
||||||
@@ -50,7 +52,7 @@ handle state0 cache execute1
|
|||||||
-- "/stop" ->
|
-- "/stop" ->
|
||||||
-- "/start" ->
|
-- "/start" ->
|
||||||
"/gfshell" -> inDir qs $ look "command" . command
|
"/gfshell" -> inDir qs $ look "command" . command
|
||||||
"/upload" -> inDir qs upload
|
"/cloud" -> inDir qs $ look "command" . cloud
|
||||||
'/':rpath ->
|
'/':rpath ->
|
||||||
case (takeDirectory path,takeFileName path,takeExtension path) of
|
case (takeDirectory path,takeFileName path,takeExtension path) of
|
||||||
(_ ,_ ,".pgf") -> wrapCGI $ PS.cgiMain' cache path
|
(_ ,_ ,".pgf") -> wrapCGI $ PS.cgiMain' cache path
|
||||||
@@ -97,15 +99,51 @@ handle state0 cache execute1
|
|||||||
let state' = maybe state (flip (M.insert dir) state) st'
|
let state' = maybe state (flip (M.insert dir) state) st'
|
||||||
return (state',ok200 output)
|
return (state',ok200 output)
|
||||||
|
|
||||||
upload dir files=
|
cloud dir cmd qs =
|
||||||
|
case cmd of
|
||||||
|
"upload" -> upload qs
|
||||||
|
"ls" -> jsonList
|
||||||
|
"rm" -> look "file" rm qs
|
||||||
|
"download" -> look "file" download qs
|
||||||
|
"link_directories" -> look "newdir" (link_directories dir) qs
|
||||||
|
_ -> return (state,resp400 $ "cloud command "++cmd)
|
||||||
|
|
||||||
|
upload files =
|
||||||
do let update (name,contents)= updateFile (name++".gf") contents
|
do let update (name,contents)= updateFile (name++".gf") contents
|
||||||
mapM_ update files
|
mapM_ update files
|
||||||
return (state,resp204)
|
return (state,resp204)
|
||||||
|
|
||||||
grammarList dir =
|
jsonList =
|
||||||
do paths <- liftIO $ getDirectoryContents dir
|
do jsons <- ls_ext "." ".json"
|
||||||
let pgfs = [path|path<-paths, takeExtension path==".pgf"]
|
return (state,ok200 (unwords jsons))
|
||||||
outputJSONP pgfs
|
|
||||||
|
rm path _ | takeExtension path==".json" =
|
||||||
|
do b <- doesFileExist path
|
||||||
|
if b
|
||||||
|
then do removeFile path
|
||||||
|
return (state,ok200 "")
|
||||||
|
else return (state,resp404 path)
|
||||||
|
rm path _ = return (state,resp400 $ "unacceptable file "++path)
|
||||||
|
|
||||||
|
download path _ = (,) state `fmap` serveStaticFile path
|
||||||
|
|
||||||
|
link_directories olddir newdir@('/':'t':'m':'p':'/':_) _ | olddir/=newdir =
|
||||||
|
do setCurrentDirectory ".."
|
||||||
|
st <- getFileStatus old
|
||||||
|
if isSymbolicLink st then removeLink old else removeDir old
|
||||||
|
createSymbolicLink new old
|
||||||
|
return (state,ok200 "")
|
||||||
|
where
|
||||||
|
old = takeFileName olddir
|
||||||
|
new = takeFileName newdir
|
||||||
|
link_directories olddir newdir _ =
|
||||||
|
return (state,resp400 $ "unacceptable directories "++olddir++" "++newdir)
|
||||||
|
|
||||||
|
grammarList dir = outputJSONP =<< liftIO (ls_ext dir ".pgf")
|
||||||
|
|
||||||
|
ls_ext dir ext =
|
||||||
|
do paths <- getDirectoryContents dir
|
||||||
|
return [path | path<-paths, takeExtension path==ext]
|
||||||
|
|
||||||
-- * Static content
|
-- * Static content
|
||||||
|
|
||||||
@@ -117,10 +155,13 @@ serveStaticFile path =
|
|||||||
serveStaticFile' path'
|
serveStaticFile' path'
|
||||||
|
|
||||||
serveStaticFile' path =
|
serveStaticFile' path =
|
||||||
do b <- doesFileExist path
|
do let ext = takeExtension path
|
||||||
let (t,rdFile,encode) = contentTypeFromExt (takeExtension path)
|
(t,rdFile,encode) = contentTypeFromExt ext
|
||||||
if b then fmap (ok200' (ct t) . encode) $ rdFile path
|
if ext `elem` [".cgi",".fcgi",".sh",".php"]
|
||||||
else return (resp404 path)
|
then return $ resp400 $ "Unsupported file type: "++ext
|
||||||
|
else do b <- doesFileExist path
|
||||||
|
if b then fmap (ok200' (ct t) . encode) $ rdFile path
|
||||||
|
else return (resp404 path)
|
||||||
|
|
||||||
-- * Logging
|
-- * Logging
|
||||||
logPutStrLn = putStrLn
|
logPutStrLn = putStrLn
|
||||||
@@ -168,6 +209,12 @@ newDirectory =
|
|||||||
Left _ -> newDirectory
|
Left _ -> newDirectory
|
||||||
Right _ -> return ('/':path)
|
Right _ -> return ('/':path)
|
||||||
|
|
||||||
|
-- | Remove a directory and the files in it, but not recursively
|
||||||
|
removeDir dir =
|
||||||
|
do files <- filter (`notElem` [".",".."]) `fmap` getDirectoryContents dir
|
||||||
|
mapM (removeFile . (dir</>)) files
|
||||||
|
removeDirectory dir
|
||||||
|
|
||||||
-- * misc utils
|
-- * misc utils
|
||||||
|
|
||||||
decodeQ qs = [(decode n,decode v)|(n,v)<-qs]
|
decodeQ qs = [(decode n,decode v)|(n,v)<-qs]
|
||||||
|
|||||||
Reference in New Issue
Block a user