1949catering.com

Final Enhancements for My Julia Web Package: Toolips Remote

Written on

Introduction to Toolips Remote

In the last three months, I have dedicated considerable effort to developing a web framework in Julia known as Toolips, which has since expanded into a broader ecosystem. Currently, this ecosystem consists of six completed packages, with several additional ones in development. Although progress on these packages has slowed, I anticipate that it won't be long before the initial features are fully operational. One of the packages nearing completion is ToolipsRemote, which requires a few final enhancements before its official launch.

Enhancing Remote Connections and User Groups

I've often discussed the potential for creating server extensions for Toolips and have even developed a few examples on my blog. However, extending Toolips can take various forms beyond just server extensions and reusable components. One effective method is through the use of connections. In this section, I will demonstrate how we can modify the AbstractConnection type to enhance Toolips's functionality by encapsulating this package.

To understand user groups, let's examine the current fields of the Remote extension:

Copytype::Vector{Symbol}

remotefunction::Function

f::Function

logins::Dict{String, Vector{UInt8}}

users::Dict{Vector{UInt8}, String}

motd::String

These fields require some adjustments to support distinct user groups, as each group should have its own set of remote functions. To facilitate this, I will make slight modifications to the data structure.

We’ll look at the parameters for the inner constructor:

function Remote(remotefunction::Function = controller(),

users::Vector{Pair{String, String}} = ["root" => "1234"];

motd::String = """### login to toolips remote session""",

serving_f::Function = serve_remote)

The remotefunction is triggered after a user logs in with the specified String from their REPL. The users field is a vector of username-password pairs, necessary for initializing Toolips remote. The motd is the message displayed when a user connects, and serving_f is the login function—this is typically not altered.

The primary modification involves changing the users vector from a Vector{Pair{String, String}} to a Vector{Pair{String, Pair}}, incorporating both the password and the user group. Additionally, the remotefunction will become a dictionary indexed by user groups, allowing for more flexible remote serving.

Copytype::Vector{Symbol}

remotefunction::Dict{Int64, Function}

f::Function

logins::Dict{String, Vector{UInt8}}

users::Dict{Vector{UInt8}, Pair{String, Int64}}

motd::String

Next, let's update the constructor to align with these changes:

remotefunction::Dict{Int64, Function} = Dict(1 => controller())

users::Vector{Pair{String, Pair}} = ["root" => "1234" => 1]

We’ll integrate this into the function:

function Remote(remotefunction::Dict{Int64, Function} = Dict(1 => controller()),

users::Vector{Pair{String, Pair}} = ["root" => "1234" => 1];

motd::String = """### login to toolips remote session""",

serving_f::Function = serve_remote)

logins::Dict{String, Vector{UInt8}} = Dict(

[n[1] => sha256(n[2]) for n in users])

users = Dict{Vector{UInt8}, Pair{String, Int64}}()

f(r::Vector{AbstractRoute}, e::Vector{ServerExtension}) = begin

r["/remote/connect"] = serving_f

end

new([:routing, :connection], remotefunction, f, logins, users,

motd)::Remote

end

In conclusion, we will adjust the serve_remote function to accommodate the new user group structure. This function now retrieves the user group of the connecting user, indexing the remotefunction field accordingly.

function serve_remote(c::Connection)

message = getpost(c)

keybeg = findall(":SESSIONKEY:", message)

if length(keybeg) == 1

keystart = keybeg[1][2] + 11

key = message[keystart:length(message)]

message = message[1:keybeg[1][1] - 1]

print(message)

if sha256(key) in keys(c[:Remote].users)

group = c[:Remote].users[sha256(key)][2]

c[:Remote].remotefunction[group](c, message, c[:Remote].users[sha256(key)])

else

write!(c, "Key invalid.")

end

end

end

Creating New Remote Connections

Before we proceed with writing this new connection, let’s refer to the Toolips.AbstractConnection documentation to learn more about connection structures.

mutable struct RemoteConnection <: Toolips.AbstractConnection

routes::Vector{Toolips.AbstractRoute}

http::Any

extensions::Vector{Toolips.ServerExtension}

end

The HTTP field can remain as Any for now. Additionally, we will add user data, which includes both the group and username:

mutable struct RemoteConnection <: Toolips.AbstractConnection

routes::Vector{Toolips.AbstractRoute}

http::Any

extensions::Vector{Toolips.ServerExtension}

group::Int64

name::String

end

An inner constructor will be created to instantiate this structure from the previous user data:

mutable struct RemoteConnection <: Toolips.AbstractConnection

routes::Vector{Toolips.AbstractRoute}

http::Any

extensions::Vector{Toolips.ServerExtension}

group::Int64

name::String

function RemoteConnection(c::Connection, userdata::Pair{String, Int64})

new(c.routes, c.http, c.extensions, userdata[2], userdata[1])

end

end

This constructor will be invoked in the serve_remote function to create new connections.

if sha256(key) in keys(c[:Remote].users)

userinfo = c[:Remote].users[sha256(key)]

newc = RemoteConnection(c, userinfo)

c[:Remote].remotefunction[userinfo[2]](newc)

else

Let's proceed with dispatching functions for various components, ensuring that they render correctly as markdown.

function write!(c::RemoteConnection, s::Component{<:Any})

write!(c, s[:text])

end

We will also define specific functions for other elements such as dividers and headings.

Testing the Final Implementation

Now it's time to create a new web application:

using Toolips

Toolips.new_app("RemoteTest")

After addressing some minor errors and importing necessary functions, I tested the new remote connection.

connect("http://127.0.0.1:8000")

The connection was successful, and I was able to interact with the remote session, indicating that the enhancements to the ToolipsRemote package are on track for release.

Video Demonstrations

To further illustrate the progress made, here are two relevant videos:

  1. Putting Final Touches on Our Bathrooms | Building Our Own Home

    This video showcases the final enhancements in a practical project setting, demonstrating the importance of detail in development.

  2. Music Production Live Episode 95 - Putting the Finishing Touch on a New Electronic Track

    This episode dives into the creative process of completing a music track, paralleling the iterative improvements made in software development.

Conclusion

The progress on the ToolipsRemote package is exciting, as it allows for both website and remote instance serving through a unified function. This development not only enhances functionality but also lays the groundwork for future extensions. I am thrilled to share my first Connection extension and look forward to publishing this package to the Julia General Registry soon. Thank you for following along!

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Embracing God's Will: Lessons from Jeremiah 27

Explore Jeremiah 27's teachings on obedience and submission to God, emphasizing the consequences of turning away from Him.

The Art of Going Dark: Finding Balance in Isolation

Exploring the concept of going dark during stressful times and the importance of balance in overcoming challenges.

Five Essential Habits for Achieving Mental Clarity and Focus

Discover five transformative habits that can enhance your focus and mental clarity in today's distraction-filled world.

Mastering Self-Control: Strategies to Tame Temptation

Explore effective strategies for managing temptation and enhancing self-control through pre-commitment techniques.

Embracing Change: Navigating the Journey to the Fifth Dimension

Discover the power of intuition and resilience on your spiritual journey to the fifth dimension.

Unlocking Your Earning Potential as a Solopreneur in 2023

Discover how to thrive as a solopreneur in 2023 with these practical tips and strategies for success.

Embrace Open-Mindedness: Four Essential Techniques for Growth

Discover four powerful techniques to cultivate open-mindedness and enhance critical thinking for personal growth.

Hydrogen: The Essential Element that Powers the Universe

Discover hydrogen's significance as the universe's most abundant element, its role in life, and its unique properties.