summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhallgren <hallgren@chalmers.se>2011-10-10 16:16:16 +0000
committerhallgren <hallgren@chalmers.se>2011-10-10 16:16:16 +0000
commit04d2dc757c34d76711a237b583855e111e4486a7 (patch)
tree661290c488e61c36ac5c64f0efd4f54768a19fa0 /src
parent5b980dcb930a1fe380e28fb9905db64e1da37672 (diff)
More functionality in "gf -server" mode
"gf -server" mode now includes PGF service and the services to support example-based grammar writing. (But gf -server is not quite ready to replace pgf-http yet...) Also bumped GF version number to 3.2.10-darcs
Diffstat (limited to 'src')
-rw-r--r--src/compiler/GFServer.hs54
-rw-r--r--src/editor/simple/cloud.js2
-rw-r--r--src/editor/simple/cloud2.js2
-rw-r--r--src/editor/simple/example_based.js10
-rw-r--r--src/editor/simple/index.html3
-rw-r--r--src/example-based/ExampleService.hs46
-rw-r--r--src/example-based/gf-exb.cabal2
-rw-r--r--src/server/RunHTTP.hs2
8 files changed, 76 insertions, 45 deletions
diff --git a/src/compiler/GFServer.hs b/src/compiler/GFServer.hs
index 75ff7bd3d..834e3f808 100644
--- a/src/compiler/GFServer.hs
+++ b/src/compiler/GFServer.hs
@@ -6,44 +6,67 @@ import System.Random(randomRIO)
import System.IO(stdout,stderr)
import System.IO.Error(try,ioError)
import System.Directory(doesDirectoryExist,doesFileExist,createDirectory,
- setCurrentDirectory,getCurrentDirectory)
-import System.FilePath(takeExtension,(</>))
+ setCurrentDirectory,getCurrentDirectory,
+ getDirectoryContents)
+import System.FilePath(takeExtension,takeFileName,takeDirectory,(</>))
import Control.Concurrent.MVar(newMVar,modifyMVar)
import Network.URI(URI(..))
import Network.Shed.Httpd(initServer,Request(..),Response(..),queryToArguments,
noCache)
+import Network.CGI(handleErrors,liftIO)
+import FastCGIUtils(outputJSONP,handleCGIErrors)
import System.IO.Silently(hCapture)
import Codec.Binary.UTF8.String(encodeString)
import GF.Infra.UseIO(readBinaryFile)
+import qualified PGFService as PS
+import qualified ExampleService as ES
+import Paths_gf(getDataDir)
+import RunHTTP(Options(..),cgiHandler)
-- * Configuraiton
-port = 41295
-documentRoot = "."
+
+options = Options { documentRoot = "." {-datadir</>"www"-}, port = gfport }
+gfport = 41296
-- * HTTP server
server execute1 state0 =
do state <- newMVar M.empty
- putStrLn $ "Starting server on port "++show port
- initServer port (modifyMVar state . handle state0 execute1)
+ cache <- PS.newPGFCache
+ --datadir <- getDataDir
+ putStrLn $ "Starting server on port "++show gfport
+ initServer gfport (modifyMVar state . handle state0 cache execute1)
-- * HTTP request handler
-handle state0 execute1 (Request method URI{uriPath=path,uriQuery=q} hdrs body) state =
+handle state0 cache execute1
+ rq@(Request method URI{uriPath=upath,uriQuery=q} hdrs body) state =
do let qs = decodeQ $
case method of
"GET" -> queryToArguments q
"POST" -> queryToArguments body
- logPutStrLn $ method++" "++path++" "++show qs
- case path of
+ logPutStrLn $ method++" "++upath++" "++show qs
+ case upath of
"/new" -> new
-- "/stop" ->
-- "/start" ->
"/gfshell" -> inDir qs $ look "command" . command
"/upload" -> inDir qs upload
- '/':rpath -> do resp <- serveStaticFile (translatePath rpath)
- return (state,resp)
- _ -> return (state,resp400 path)
+ '/':rpath ->
+ case (takeDirectory path,takeFileName path,takeExtension path) of
+ (_ ,_ ,".pgf") -> wrapCGI $ PS.cgiMain' cache path
+ (dir,"grammars.cgi",_ ) -> wrapCGI $ grammarList dir
+ (dir ,"exb.fcgi" ,_ ) -> wrapCGI $ ES.cgiMain' root dir cache
+ _ -> do resp <- serveStaticFile path
+ return (state,resp)
+ where path = translatePath rpath
+ _ -> return (state,resp400 upath)
where
+ root = documentRoot options
+
+ wrapCGI cgi =
+ do resp <- cgiHandler root (handleErrors . handleCGIErrors $ cgi) rq
+ return (state,resp)
+
look field ok qs =
case partition ((==field).fst) qs of
((_,value):qs1,qs2) -> ok value (qs1++qs2)
@@ -79,9 +102,14 @@ handle state0 execute1 (Request method URI{uriPath=path,uriQuery=q} hdrs body) s
mapM_ update files
return (state,resp204)
+ grammarList dir =
+ do paths <- liftIO $ getDirectoryContents dir
+ let pgfs = [path|path<-paths, takeExtension path==".pgf"]
+ outputJSONP pgfs
+
-- * Static content
-translatePath path = documentRoot</>path -- hmm, check for ".."
+translatePath path = documentRoot options</>path -- hmm, check for ".."
serveStaticFile path =
do b <- doesDirectoryExist path
diff --git a/src/editor/simple/cloud.js b/src/editor/simple/cloud.js
index fad66e1ff..44b7d8157 100644
--- a/src/editor/simple/cloud.js
+++ b/src/editor/simple/cloud.js
@@ -137,7 +137,7 @@ function gfshell(cmd,cont) {
// Check the syntax of an expression
function check_exp(s,cont) {
function check(gf_message) {
- debug("cc "+s+" = "+gf_message);
+ //debug("cc "+s+" = "+gf_message);
cont(/parse error/.test(gf_message) ? "parse error" : null);
}
if(navigator.onLine)
diff --git a/src/editor/simple/cloud2.js b/src/editor/simple/cloud2.js
index 2331b39f2..c57922438 100644
--- a/src/editor/simple/cloud2.js
+++ b/src/editor/simple/cloud2.js
@@ -63,7 +63,7 @@ function gfshell(cmd,cont) {
// Check the syntax of an expression
function check_exp(s,cont) {
function check(gf_message) {
- debug("cc "+s+" = "+gf_message);
+ //debug("cc "+s+" = "+gf_message);
cont(/parse error/.test(gf_message) ? "parse error" : null);
}
gfshell("cc "+s,check);
diff --git a/src/editor/simple/example_based.js b/src/editor/simple/example_based.js
index 83fde0f6c..1fb13740a 100644
--- a/src/editor/simple/example_based.js
+++ b/src/editor/simple/example_based.js
@@ -31,9 +31,11 @@ function exb_state(g,ci) {
}
function exb_call(g,ci,command,args,cont) {
- var url="exb/exb.fcgi?command="+command+"&state="+exb_state(g,ci);
- for(var arg in args) url+="&"+arg+"="+encodeURIComponent(args[arg]);
- http_get_json(url,cont)
+ var url=window.exb_url || "exb/exb.fcgi";
+ var q=""
+ for(var arg in args) q+="&"+arg+"="+encodeURIComponent(args[arg]);
+ var cmd="?command="+command+"&state="+encodeURIComponent(exb_state(g,ci))+q;
+ http_get_json(url+cmd,cont)
}
function ask_possibilities(g,ci) {
@@ -126,7 +128,7 @@ function exb_linbuttons(g,ci,f) {
exb_call(g,ci,"provide_example",
{lang:g.basename+conc.example_lang,
fun:fun,
- grammar:"."+dir+"/"+g.basename+".pgf"},
+ grammar:dir+"/"+g.basename+".pgf"},
show_example)
}
}
diff --git a/src/editor/simple/index.html b/src/editor/simple/index.html
index de5efa373..27b053300 100644
--- a/src/editor/simple/index.html
+++ b/src/editor/simple/index.html
@@ -32,10 +32,11 @@ This page does not work without JavaScript.
<hr>
<div class=modtime><small>
HTML
-<!-- hhmts start --> Last modified: Tue Sep 27 15:41:36 CEST 2011 <!-- hhmts end -->
+<!-- hhmts start --> Last modified: Mon Oct 10 17:54:37 CEST 2011 <!-- hhmts end -->
</small></div>
<a href="about.html">About</a>
<pre id=debug></pre>
+<script type="text/javascript" src="config.js"></script> <!-- optional -->
<script type="text/javascript" src="support.js"></script>
<script type="text/javascript" src="localstorage.js"></script>
<script type="text/javascript" src="gf_abs.js"></script>
diff --git a/src/example-based/ExampleService.hs b/src/example-based/ExampleService.hs
index 165caccba..e4198a87b 100644
--- a/src/example-based/ExampleService.hs
+++ b/src/example-based/ExampleService.hs
@@ -1,4 +1,5 @@
-module ExampleService(cgiMain,newPGFCache) where
+module ExampleService(cgiMain,cgiMain',newPGFCache) where
+import System.FilePath((</>),makeRelative)
import Data.Map(fromList)
import Data.Char(isDigit)
import Data.Maybe(fromJust)
@@ -14,31 +15,30 @@ newPGFCache = newCache readPGF
cgiMain :: Cache PGF -> CGI CGIResult
-cgiMain cache =
- handleErrors . handleCGIErrors $
- do command <- getInp "command"
- environ <- parseEnviron =<< getInp "state"
- cgiMain' cache command environ
-
-cgiMain' cache command environ =
- case command of
- "possibilities" -> outputJSONP (E.getNext environ)
- "provide_example" -> doProvideExample cache environ
- "abstract_example" -> doAbstractExample cache environ
- "test_function" -> doTestFunction cache environ
- _ -> throwCGIError 400 ("Unknown command: "++command) []
-
-doProvideExample cache environ =
+cgiMain = handleErrors . handleCGIErrors . cgiMain' "." "."
+
+cgiMain' root cwd cache =
+ do command <- getInp "command"
+ environ <- parseEnviron =<< getInp "state"
+ case command of
+ "possibilities" -> outputJSONP (E.getNext environ)
+ "provide_example" -> doProvideExample root cwd cache environ
+ "abstract_example" -> doAbstractExample cwd cache environ
+ "test_function" -> doTestFunction cwd cache environ
+ _ -> throwCGIError 400 ("Unknown command: "++command) []
+
+doProvideExample root cwd cache environ =
do Just lang <- readInput "lang"
fun <- getCId "fun"
- parsePGF <- readParsePGF cache
- pgf <- liftIO . readCache cache =<< getInp "grammar"
+ parsePGF <- readParsePGF cwd cache
+ let adjpath path = root</>makeRelative "/" (makeRelative root cwd</>path)
+ pgf <- liftIO . readCache cache . adjpath =<< getInp "grammar"
let Just (e,s) = E.provideExample environ fun parsePGF pgf lang
res = (showExpr [] e,s)
liftIO $ logError $ "proveExample ... = "++show res
outputJSONP res
-doAbstractExample cache environ =
+doAbstractExample cwd cache environ =
do example <- getInp "input"
Just params <- readInput "params"
absstr <- getInp "abstract"
@@ -46,7 +46,7 @@ doAbstractExample cache environ =
liftIO $ logError $ "abstract = "++showExpr [] abs
Just cat <- readInput "cat"
let t = mkType [] cat []
- parsePGF <- readParsePGF cache
+ parsePGF <- readParsePGF cwd cache
let lang:_ = languages parsePGF
ae <- liftIO $ abstractExample parsePGF environ lang t abs example
outputJSONP (fmap (\(e,_)->(exprToAPI (instExpMeta params e),e)) ae)
@@ -54,9 +54,9 @@ doAbstractExample cache environ =
abstractExample parsePGF env lang cat abs example =
E.searchGoodTree env abs (parse parsePGF lang cat example)
-doTestFunction cache environ =
+doTestFunction cwd cache environ =
do fun <- getCId "fun"
- parsePGF <- readParsePGF cache
+ parsePGF <- readParsePGF cwd cache
let lang:_ = languages parsePGF
Just txt <- return (E.testThis environ fun parsePGF lang)
outputJSONP txt
@@ -70,7 +70,7 @@ getLimit = maybe err return =<< readInput "limit"
where err = throwCGIError 400 "Missing/bad limit" []
-readParsePGF cache = liftIO $ readCache cache "ParseEngAbs.pgf"
+readParsePGF cwd cache = liftIO $ readCache cache (cwd</>"ParseEngAbs.pgf")
parseEnviron s = do state <- liftIO $ readIO s
return $ environ state
diff --git a/src/example-based/gf-exb.cabal b/src/example-based/gf-exb.cabal
index 75b1a49a1..1366e75da 100644
--- a/src/example-based/gf-exb.cabal
+++ b/src/example-based/gf-exb.cabal
@@ -17,7 +17,7 @@ executable exb.fcgi
build-depends: base >=4.2 && <5, json, cgi, fastcgi, random,
containers, old-time, directory, bytestring, utf8-string,
- pretty, array, mtl, fst
+ pretty, array, mtl, fst, filepath
if os(windows)
ghc-options: -optl-mwindows
diff --git a/src/server/RunHTTP.hs b/src/server/RunHTTP.hs
index 0047d68a3..2afc92afc 100644
--- a/src/server/RunHTTP.hs
+++ b/src/server/RunHTTP.hs
@@ -1,4 +1,4 @@
-module RunHTTP(runHTTP,Options(..)) where
+module RunHTTP(runHTTP,Options(..),cgiHandler) where
import Network.URI(uriPath,uriQuery)
import Network.CGI(ContentType(..))
import Network.CGI.Protocol(CGIResult(..),CGIRequest(..),Input(..),