2016-01-05 20:34:07 +00:00
|
|
|
# NimYAML - YAML implementation in Nim
|
|
|
|
# (c) Copyright 2015 Felix Krause
|
|
|
|
#
|
|
|
|
# See the file "copying.txt", included in this
|
|
|
|
# distribution, for details about the copyright.
|
|
|
|
|
2023-09-04 20:48:04 +00:00
|
|
|
import jester, parseopt, asyncdispatch, json, streams, strutils
|
2021-05-17 18:33:05 +00:00
|
|
|
import packages/docutils/rstgen, packages/docutils/highlite, options
|
2023-09-04 20:48:04 +00:00
|
|
|
import ../yaml, ../yaml/parser, ../yaml/presenter, server_cfg
|
2016-01-05 20:34:07 +00:00
|
|
|
|
2022-06-03 23:45:41 +00:00
|
|
|
router nyRouter:
|
|
|
|
get "/webservice/":
|
2021-05-17 17:50:10 +00:00
|
|
|
resp(Http200, [("Content-Type", "text/plain")], "I am a friendly NimYAML parser webservice.")
|
2022-06-03 23:45:41 +00:00
|
|
|
post "/webservice/":
|
2016-04-02 15:48:22 +00:00
|
|
|
var
|
|
|
|
resultNode = newJObject()
|
2016-10-01 12:49:32 +00:00
|
|
|
msg: string
|
|
|
|
retStatus = Http200
|
|
|
|
contentType = "application/json"
|
2021-05-17 17:50:10 +00:00
|
|
|
headers = @[("Access-Control-Allow-Origin", "*"), ("Pragma", "no-cache"),
|
|
|
|
("Cache-Control", "no-cache"), ("Expires", "0")]
|
2023-09-04 20:48:04 +00:00
|
|
|
dumper: Dumper
|
2016-04-02 15:48:22 +00:00
|
|
|
try:
|
|
|
|
case @"style"
|
2023-09-04 20:48:04 +00:00
|
|
|
of "minimal": dumper.setMinimalStyle()
|
|
|
|
of "canonical": dumper.setCanonicalStyle()
|
|
|
|
of "default": dumper.setDefaultStyle()
|
|
|
|
of "json": dumper.setJsonStyle()
|
|
|
|
of "block": dumper.setBlockOnlyStyle()
|
2016-04-02 15:48:22 +00:00
|
|
|
of "tokens":
|
2023-03-13 21:52:59 +00:00
|
|
|
try:
|
|
|
|
var
|
|
|
|
output = "+STR\n"
|
|
|
|
parser = initYamlParser(false)
|
|
|
|
events = parser.parse(newStringStream(@"input"))
|
|
|
|
for event in events: output.add(parser.display(event) & "\n")
|
|
|
|
output &= "-STR"
|
|
|
|
resultNode["code"] = %0
|
|
|
|
resultNode["output"] = %output
|
|
|
|
msg = resultNode.pretty
|
|
|
|
except YamlStreamError as e:
|
|
|
|
raise e.parent
|
2016-10-01 12:49:32 +00:00
|
|
|
else:
|
|
|
|
retStatus = Http400
|
|
|
|
msg = "Invalid style: " & escape(@"style")
|
|
|
|
contentType = "text/plain;charset=utf8"
|
2021-05-17 17:50:10 +00:00
|
|
|
if len(msg) == 0:
|
2016-05-12 13:35:29 +00:00
|
|
|
var
|
|
|
|
output = newStringStream()
|
|
|
|
highlighted = ""
|
2023-09-04 20:48:04 +00:00
|
|
|
dumper.transform(newStringStream(@"input"), output, true)
|
2016-10-01 12:49:32 +00:00
|
|
|
|
2016-05-12 13:35:29 +00:00
|
|
|
# syntax highlighting (stolen and modified from stlib's rstgen)
|
|
|
|
var g: GeneralTokenizer
|
|
|
|
g.initGeneralTokenizer(output.data)
|
|
|
|
while true:
|
|
|
|
g.getNextToken(langYaml)
|
|
|
|
case g.kind
|
|
|
|
of gtEof: break
|
|
|
|
of gtNone, gtWhitespace:
|
|
|
|
highlighted.add(substr(output.data, g.start, g.length + g.start - 1))
|
|
|
|
else:
|
2021-05-17 18:33:05 +00:00
|
|
|
highlighted.addf("<span class=\"$2\">$1</span>",
|
2016-05-12 13:35:29 +00:00
|
|
|
esc(outHtml, substr(output.data, g.start, g.length+g.start-1)),
|
2021-05-17 17:50:10 +00:00
|
|
|
tokenClassToStr[g.kind])
|
2016-05-12 13:35:29 +00:00
|
|
|
|
2016-04-02 15:48:22 +00:00
|
|
|
resultNode["code"] = %0
|
2016-05-12 13:35:29 +00:00
|
|
|
resultNode["output"] = %highlighted
|
2016-10-01 12:49:32 +00:00
|
|
|
msg = resultNode.pretty
|
2023-03-18 12:54:45 +00:00
|
|
|
except YamlParserError as e:
|
2016-04-02 15:48:22 +00:00
|
|
|
resultNode["code"] = %1
|
2021-05-17 17:50:10 +00:00
|
|
|
resultNode["line"] = %e.mark.line
|
|
|
|
resultNode["column"] = %e.mark.column
|
2016-04-02 15:48:22 +00:00
|
|
|
resultNode["message"] = %e.msg
|
|
|
|
resultNode["detail"] = %e.lineContent
|
2016-10-01 12:49:32 +00:00
|
|
|
msg = resultNode.pretty
|
2023-03-18 12:54:45 +00:00
|
|
|
except YamlPresenterJsonError as e:
|
2016-04-02 15:48:22 +00:00
|
|
|
resultNode["code"] = %2
|
|
|
|
resultNode["message"] = %e.msg
|
2016-10-01 12:49:32 +00:00
|
|
|
msg = resultNode.pretty
|
2023-03-18 12:54:45 +00:00
|
|
|
except CatchableError as e:
|
2016-10-01 12:49:32 +00:00
|
|
|
msg = "Name: " & $e.name & "\nMessage: " & e.msg &
|
|
|
|
"\nTrace:\n" & e.getStackTrace
|
|
|
|
retStatus = Http500
|
|
|
|
contentType = "text/plain;charset=utf-8"
|
2021-05-17 17:50:10 +00:00
|
|
|
headers.add(("Content-Type", contentType))
|
|
|
|
resp retStatus, headers, msg
|
2022-06-03 23:45:41 +00:00
|
|
|
|
2023-09-04 20:48:04 +00:00
|
|
|
proc main(port: int, address: string) =
|
2022-06-03 23:45:41 +00:00
|
|
|
let settings = newSettings(port=port.Port, bindAddr=address, staticDir=shareDir())
|
|
|
|
var jester = initJester(nyrouter, settings=settings)
|
|
|
|
jester.serve()
|
|
|
|
|
|
|
|
when isMainModule:
|
2023-09-04 20:48:04 +00:00
|
|
|
var
|
|
|
|
port = 5000
|
|
|
|
address = "127.0.0.1"
|
|
|
|
for kind, key, value in getOpt():
|
|
|
|
case kind
|
|
|
|
of cmdArgument:
|
|
|
|
echo "unexpected positional argument"
|
|
|
|
quit 1
|
|
|
|
of cmdLongOption, cmdShortOption:
|
|
|
|
case key
|
|
|
|
of "p", "port":
|
|
|
|
port = parseInt(value)
|
|
|
|
of "a", "address":
|
|
|
|
address = value
|
|
|
|
else:
|
|
|
|
echo "Unknown option: ", key
|
|
|
|
quit 1
|
|
|
|
of cmdEnd:
|
|
|
|
discard
|
|
|
|
main(port, address)
|