Skip to content

Commit 36bf092

Browse files
author
Adrian Salceanu
committed
+ v4.3
+ Sessions API improvements + optimized HTML parsing of Julia UIs + Small improvements in AppServer API
1 parent 502c5a8 commit 36bf092

File tree

7 files changed

+79
-23
lines changed

7 files changed

+79
-23
lines changed

CHANGELOG.html

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<html>
22
<head>
3-
<script async src="https://www.googletagmanager.com/gtag/js?id=G-FNFE1QBFCP"></script>
3+
<!-- Google Tag Manager (noscript) -->
4+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-P6WZFKS"
5+
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
6+
<!-- End Google Tag Manager (noscript) -->
47
</head>
58
<body>
69
<code>

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Genie"
22
uuid = "c43c736e-a2d1-11e8-161f-af95117fbd1e"
33
authors = ["Adrian Salceanu <[email protected]>"]
4-
version = "4.2.0"
4+
version = "4.3.0"
55

66
[deps]
77
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"

src/AppServer.jl

+14
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ end
187187
down(; webserver::Bool = true, websockets::Bool = true) :: ServersCollection
188188
189189
Shuts down the servers optionally indicating which of the `webserver` and `websockets` servers to be stopped.
190+
It does not remove the servers from the `SERVERS` collection. Returns the collection.
190191
"""
191192
function down(; webserver::Bool = true, websockets::Bool = true) :: Vector{ServersCollection}
192193
for i in 1:length(SERVERS)
@@ -205,6 +206,19 @@ function down(server::ServersCollection; webserver::Bool = true, websockets::Boo
205206
end
206207

207208

209+
"""
210+
function down!(; webserver::Bool = true, websockets::Bool = true) :: Vector{ServersCollection}
211+
212+
Shuts down all the servers and empties the `SERVERS` collection. Returns the empty collection.
213+
"""
214+
function down!() :: Vector{ServersCollection}
215+
down()
216+
empty!(SERVERS)
217+
218+
SERVERS
219+
end
220+
221+
208222
"""
209223
handle_request(req::HTTP.Request, res::HTTP.Response) :: HTTP.Response
210224

src/Assets.jl

+7-7
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ end
187187
188188
Outputs the channels.js file included with the Genie package
189189
"""
190-
function channels(channel::String = Genie.config.webchannels_default_route) :: String
191-
string(js_settings(channel), embedded(Genie.Assets.asset_file(cwd=normpath(joinpath(@__DIR__, "..")), type="js", file="channels")))
190+
function channels(channel::AbstractString = Genie.config.webchannels_default_route) :: String
191+
string(js_settings(channel), embedded(Genie.Assets.asset_file(cwd=normpath(joinpath(@__DIR__, "..")), type = "js", file = "channels")))
192192
end
193193

194194

@@ -197,7 +197,7 @@ end
197197
198198
Outputs the channels JavaScript content within `<script>...</script>` tags, for embedding into the page.
199199
"""
200-
function channels_script(channel::String = Genie.config.webchannels_default_route) :: String
200+
function channels_script(channel::AbstractString = Genie.config.webchannels_default_route) :: String
201201
"""
202202
<script>
203203
$(channels(channel))
@@ -206,7 +206,7 @@ $(channels(channel))
206206
end
207207

208208

209-
function channels_subscribe(channel::String = Genie.config.webchannels_default_route) :: Nothing
209+
function channels_subscribe(channel::AbstractString = Genie.config.webchannels_default_route) :: Nothing
210210
Router.channel("/$(channel)/$(Genie.config.webchannels_subscribe_channel)") do
211211
WebChannels.subscribe(Genie.Requests.wsclient(), channel)
212212

@@ -230,8 +230,8 @@ end
230230
Provides full web channels support, setting up routes for loading support JS files, web sockets subscription and
231231
returning the `<script>` tag for including the linked JS file into the web page.
232232
"""
233-
function channels_support(channel::String = Genie.config.webchannels_default_route) :: String
234-
endpoint = Genie.Assets.asset_path(assets_config, :js, file=Genie.config.webchannels_js_file, path=channel, skip_ext = true)
233+
function channels_support(channel::AbstractString = Genie.config.webchannels_default_route) :: String
234+
endpoint = Genie.Assets.asset_path(assets_config, :js, file = Genie.config.webchannels_js_file, skip_ext = true)
235235

236236
if ! external_assets()
237237
Router.route(endpoint) do
@@ -316,7 +316,7 @@ Provides full web channels support, setting up routes for loading support JS fil
316316
returning the `<script>` tag for including the linked JS file into the web page.
317317
"""
318318
function webthreads_support(channel::String = Genie.config.webthreads_default_route) :: String
319-
endpoint = Genie.Assets.asset_path(assets_config, :js, file=Genie.config.webthreads_js_file, path=channel)
319+
endpoint = Genie.Assets.asset_path(assets_config, :js, file = Genie.config.webthreads_js_file, skip_ext = true)
320320

321321
if ! external_assets()
322322
Router.route(endpoint) do

src/Genie.jl

+1
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ const startup = AppServer.startup
222222
const up = startup
223223
const down = AppServer.down
224224
const isrunning = AppServer.isrunning
225+
const down! = AppServer.down!
225226

226227

227228
### PRIVATE ###

src/Sessions.jl

+12-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ end
1818

1919
Session(id::String) = Session(id, Dict{Symbol,Any}())
2020

21-
export Session
21+
export Session, session
2222

2323
struct InvalidSessionIdException <: Exception
2424
msg::String
@@ -93,14 +93,12 @@ end
9393
9494
Sets up the session functionality, if configured.
9595
"""
96-
function init() :: Nothing
96+
function init()
9797
@eval Genie.config.session_storage === nothing && (Genie.config.session_storage = :File)
9898
@eval Genie.config.session_storage == :File && include(joinpath(@__DIR__, "session_adapters", "FileSession.jl"))
9999

100100
push!(Genie.Router.pre_match_hooks, Genie.Sessions.start)
101101
push!(Genie.Router.pre_response_hooks, Genie.Sessions.persist)
102-
103-
nothing
104102
end
105103

106104

@@ -165,6 +163,9 @@ function set!(s::Session, key::Symbol, value::Any) :: Session
165163

166164
s
167165
end
166+
function set!(key::Symbol, value::Any) :: Session
167+
set!(session(), key, value)
168+
end
168169

169170

170171
"""
@@ -175,6 +176,9 @@ Returns the value stored on the `Session` object `s` as `key`, wrapped in a `Uni
175176
function get(s::Session, key::Symbol) :: Union{Nothing,Any}
176177
haskey(s.data, key) ? (s.data[key]) : nothing
177178
end
179+
function get(key::Symbol) :: Union{Nothing,Any}
180+
get(session(), key)
181+
end
178182

179183

180184
"""
@@ -188,6 +192,9 @@ function get(s::Session, key::Symbol, default::T) :: T where T
188192

189193
val === nothing ? default : val
190194
end
195+
function get(key::Symbol, default::T) :: T where T
196+
get(session(), key, default)
197+
end
191198

192199

193200
"""
@@ -233,7 +240,7 @@ function load end
233240
234241
Returns the `Session` object associated with the current HTTP request.
235242
"""
236-
function session(params::Dict{Symbol,Any}) :: Sessions.Session
243+
function session(params::Dict{Symbol,Any} = Genie.Router.params()) :: Sessions.Session
237244
( (! haskey(params, Genie.PARAMS_SESSION_KEY) || params[Genie.PARAMS_SESSION_KEY] === nothing) ) &&
238245
(params[Genie.PARAMS_SESSION_KEY] = Sessions.start(params[Genie.PARAMS_REQUEST_KEY], params[Genie.PARAMS_RESPONSE_KEY])[1])
239246

src/renderers/Html.jl

+40-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const MARKDOWN_FILE_EXT = [".md", ".jl.md"]
1616

1717
const SUPPORTED_HTML_OUTPUT_FILE_FORMATS = [TEMPLATE_EXT]
1818

19-
const HTMLString = String
2019
const HTMLParser = EzXML
2120

2221
const NBSP_REPLACEMENT = ("&nbsp;"=>"!!nbsp;;")
@@ -45,7 +44,33 @@ const SVG_ELEMENTS = [:animate, :circle, :animateMotion, :animateTransform, :cli
4544
const EMBEDDED_JULIA_PLACEHOLDER = "~~~~~|~~~~~"
4645

4746

48-
export HTMLString, html, doc, doctype
47+
# ParsedHTMLStrings
48+
struct ParsedHTMLString <: AbstractString
49+
data::String
50+
end
51+
52+
function ParsedHTMLString(v::Vector{T}) where {T}
53+
join(v)
54+
end
55+
56+
ParsedHTMLString(args...) = ParsedHTMLString([args...])
57+
58+
Base.string(s::ParsedHTMLString) = s.data
59+
Base.String(s::ParsedHTMLString) = string(s)
60+
61+
Base.iterate(s::ParsedHTMLString) = iterate(s.data)
62+
Base.iterate(s::ParsedHTMLString, x::Int) = iterate(s.data, x)
63+
64+
Base.convert(::Type{ParsedHTMLString}, v::Vector{T}) where {T} = ParsedHTMLString(v)
65+
66+
import Base: (*)
67+
(*)(s::ParsedHTMLString, t::ParsedHTMLString) = string(s.data, t.data)
68+
69+
# end ParsedHTMLStrings
70+
71+
const HTMLString = String
72+
73+
export HTMLString, html, doc, doctype, ParsedHTMLString
4974
export @yield, collection, view!, for_each
5075
export partial, template
5176

@@ -68,16 +93,16 @@ Generates a HTML element in the form <...></...>
6893
function normal_element(f::Function, elem::Any, args::Vector = [], attrs::Vector{Pair{Symbol,Any}} = Pair{Symbol,Any}[]) :: HTMLString
6994
normal_element(Base.invokelatest(f), string(elem), args, attrs...)
7095
end
71-
function normal_element(children::Union{String,Vector{String}}, elem::Any, args::Vector, attrs::Pair{Symbol,Any}) :: HTMLString
96+
function normal_element(children::Union{T,Vector{T}}, elem::Any, args::Vector, attrs::Pair{Symbol,Any})::HTMLString where {T<:AbstractString}
7297
normal_element(children, string(elem), args, Pair{Symbol,Any}[attrs])
7398
end
7499
function normal_element(children::Tuple, elem::Any, args::Vector, attrs::Pair{Symbol,Any}) :: HTMLString
75100
normal_element([children...], string(elem), args, Pair{Symbol,Any}[attrs])
76101
end
77-
function normal_element(children::Union{String,Vector{String}}, elem::Any, args::Vector, attrs...) :: HTMLString
102+
function normal_element(children::Union{T,Vector{T}}, elem::Any, args::Vector, attrs...)::HTMLString where {T<:AbstractString}
78103
normal_element(children, string(elem), args, Pair{Symbol,Any}[attrs...])
79104
end
80-
function normal_element(children::Union{String,Vector{String}}, elem::Any, args::Vector = [], attrs::Vector{Pair{Symbol,Any}} = Pair{Symbol,Any}[]) :: HTMLString
105+
function normal_element(children::Union{T,Vector{T}}, elem::Any, args::Vector = [], attrs::Vector{Pair{Symbol,Any}} = Pair{Symbol,Any}[])::HTMLString where {T<:AbstractString}
81106
content_args, args = contentargs(args...)
82107
children = string(join(children), content_args)
83108

@@ -301,10 +326,10 @@ end
301326
"""
302327
Outputs document's doctype.
303328
"""
304-
function doc(html::String) :: HTMLString
329+
function doc(html::AbstractString) :: HTMLString
305330
string(doctype(), html)
306331
end
307-
function doc(doctype::Symbol, html::String) :: HTMLString
332+
function doc(doctype::Symbol, html::AbstractString) :: HTMLString
308333
string(doctype(doctype), html)
309334
end
310335

@@ -445,11 +470,17 @@ function html(data::String; context::Module = @__MODULE__, status::Int = 200, he
445470
if (occursin(raw"$", data) || occursin("<%", data) || layout !== nothing || forceparse) && ! noparse
446471
Genie.Renderer.WebRenderable(Genie.Renderer.render(MIME"text/html", data; context = context, layout = layout, vars...), status, headers) |> Genie.Renderer.respond
447472
else
448-
Genie.Renderer.WebRenderable(body = data, status = status, headers = headers) |> Genie.Renderer.respond
473+
html(ParsedHTMLString(data); context, status, headers, layout, vars...)
449474
end
450475
end
451476

452477

478+
function html(data::ParsedHTMLString; context::Module = @__MODULE__, status::Int = 200, headers::Genie.Renderer.HTTPHeaders = Genie.Renderer.HTTPHeaders(),
479+
layout::Union{String,Nothing,Genie.Renderer.FilePath} = nothing, vars...) :: Genie.Renderer.HTTP.Response
480+
Genie.Renderer.WebRenderable(body = data.data, status = status, headers = headers) |> Genie.Renderer.respond
481+
end
482+
483+
453484
"""
454485
html(md::Markdown.MD; context::Module = @__MODULE__, status::Int = 200, headers::Genie.Renderer.HTTPHeaders = Genie.Renderer.HTTPHeaders(), layout::Union{String,Nothing} = nothing, forceparse::Bool = false, vars...) :: Genie.Renderer.HTTP.Response
455486
@@ -738,7 +769,7 @@ Converts an input file to Julia code
738769
partial = true, f_name::Union{Symbol,Nothing} = nothing, prepend::String = "\n", extension = TEMPLATE_EXT) :: String
739770
f_name = (f_name === nothing) ? Genie.Renderer.function_name(string(input, partial)) : f_name
740771

741-
string("function $(f_name)(; $(Genie.Renderer.injectkwvars())) \n",
772+
string("function $(f_name)(; $(Genie.Renderer.injectkwvars())) :: ParsedHTMLString \n",
742773
"
743774
[
744775
",

0 commit comments

Comments
 (0)