NovaTcl

MDD: I’m particularly excited about the potential AndroWish provides in the area of education.

I’ve worked with SEH over the last year to create an enhanced version (adding Firebase support and NetSurf web integration) of the AndroWish package, called NovaTcl [L1 ], that I intend to build upon to create an environment for teaching kids to code. I don’t care too much about the old look-and-feel of Tcl, since teaching coding concepts is the main objective. Over time, the look-and-feel issues will likely improve.

My plan is to leverage the simplicity of the language, and the low-cost of Android devices, to put together a reasonably-complete curriculum covering the various fundamentals of coding and application design, one that even poorly-funded schools can integrate into their curricula with minimal resource requirements.

I’ve released a preview version of the package in the Google Play Store (search for NovaTcl), and plan to add an integrated editing environment with interactive lessons, and other tools, by the end of the year. I’ve started putting together a web site for the project, as well, [L2 ] but it is not even close to complete. This is basically a side-project for me, but hopefully I can get some schools to try it out next year. It is only through the amazing work that chw is doing with AndroWish that this project has become even remotely feasible.


MDD: By the way, the Samsung Chromebook Plus [L3 ] is an awesome device for coding in AndroWish/NovaTcl. It combines the advantages of a full desktop version of Chrome with Android app support. Nice keyboard, big screen, good battery life, great design. Combine it with the fx file manager and a good editor like DroidEdit or QuickEdit Pro, and you have a really great dev environment.

For kids, the RCA Viking Pro 10 tablet/keyboard combo is a great choice. [L4 ] The price varies, but I've found it for $94. The keyboard is directly-connected, rather than bluetooth, which is a huge advantage when doing coding, since there's none of the sleep/wake latency you find with bluetooth keyboards. A good inexpensive phone for kids to test with is the Moto E [L5 ], whose price is usually in the $75-$100 range.


The current (v 1.8) NovaTcl release in the Play Store includes support for Google Firebase. Here is a quick doc on the Firebase package:

The Tcl package firebase allows writing to/reading from a Google Firebase
database.  

The firebase package requires the identifying project name of an existing
Firebase database, or the unique API key of the database, both available from
the Google Firebase web console interface.

For administrative access, a valid secret key string generated by Google for the
database is required.  The firebase package can generate an ID token in JWT 
format using this string; the token can be used for authentication for read and
write operations.

For client user access, the firebase package can create email/password accounts
for a database, and retrieve individual ID tokens for clients using the unique 
Google-generated API key of the database (the API key is different from the 
administrator secret key string). A user can specify an email/password using the
getToken command,  the command's code will check if an account exists with these
credentials and create an account if it doesn't, then return a valid JWT token 
for authorization. 

The firebase package can also be used to received streaming notification events
of database changes using Firebase's EventSource API.  A user can specify a
procedure which will be called in the background to receive each event's data
as events arrive from the Firebase site.

Administrator example:


% package require firebase
% set token [firebase::token $secret_string]
% firebase::put $db $token {{"a":1, "b":2}} test
% firebase::get $db $token
        {"test":{"a":1,"b":2}}


User example:

% set token [firebase::getToken [email protected] mypass $apikey]
% firebase::put $db $token {{"a":1, "b":2}} test
% firebase::delete $db $token {}
% firebase::get $db $token
        null


Event streaming example:

% set token [firebase::getToken [email protected] mypass $apikey]
% firebase::eventStream $db $token
        event: put
        data: {"path":"/","data":"test0"}


Procedures:

firebase::token secret ?uid?

generate a JWT-format token for authentication.  Optionally specify a uid to
restrict read/write access via security rules added to database.


firebase::get db token ?node?

get contents of entire database tree, or optionally contents of specified
subtree starting at node.  Returns: database contents in Tcl dict format.


firebase::put db token data ?node?

write data in JSON format to database, optionally at specified subtree node in 
the database.  Overwrites existing data.


firebase::push db token data ?node?

use Firebase "push" function to write JSON data to database without overwriting
existing data.  Google Firebase automatically generates a unique node name and 
inserts the data under that name.  Returns: unique node name generated by Google.


firebase::update db token data ?node?

change database values only of keys specified in JSON data, without overwriting
entire tree or subtree.


firebase::delete db token node

delete specified node in database tree.


firebase::signup email password apikey

if email/password authentication is enabled for the database corresponding to
the API key, create a new user account.  Returns: account state values 
(including authentication token) in key/value format as returned by Google, as a
Tcl dict.


firebase::login email password apikey

logs in to existing user account for the database corresponding to the API key.
Returns: account state values (including authentication token) in key/value 
format as returned by Google, as a Tcl dict.


firebase::getToken email password apikey

convenience function; tries to log in to account with given email and password,
if account doesn't exist the account is created.  Returns: authentication token
in JWT format for use with database read/write procedures.


firebase::eventStream db token eventproc timeout node

sets up streaming reception of events containing updates of the value of the
specified database node.  The argument "eventproc" is the name of a procedure
which will be called every time an event arrives, and passed a single argument
containing the contents of the event.


firebase::eventProc output

default callback procedure used by eventStream procedure.  Simply echoes event
data to standard output.

MDD: The Firebase functionality is untested. Please try it out and let me know how it works for you.


We've also added the NetSurf browser, though I'd call it very experimental. Here is the doc for that package:

Notes for Package tksurf:

Package tksurf can be added with the command "package require tksurf".  When the
tksurf package is loaded, a namespace variable named "::tksurf::privateDir" is
created and set to the name of a directory which is private to the Nova app,
where HTML files and other loadable resources can be stored.  Any files in the
virtual directory "/assets/tksurf/res" are copied to the location
"$::tksurf::privateDir/tksurf/res" when the tksurf package is loaded.

Package tksurf adds two commands to the interpreter:

*        ::tksurf::launch <URL>

Launches the tksurf browser window and loads the specified URL.  Any URL scheme
acceptable to Curl can be used (i.e., "http://" or "file://"). The "https://"
scheme is not enabled.  A URL specified with the "file://" scheme must point to
a real file (e.g. in the directory "$::tksurf::privateDir/tksurf/res"), not a 
file in a virtual directory such as "/assets".

*        ::tksurf::url_refresh <URL>

After the tksurf browser window is launched with a given URL, the URL displayed
by the window can be changed with this command.  The window will be reloaded
with the specified URL, under the same constraints as described for the
"tksurf::launch" command.

Tcl callbacks:

Every touch event in the tksurf browser window generates a callback to the Tcl
interpreter from which the browser was launched.  If the DOM node touched has an
"id" attribute tag, the value of that tag is stored in a Tcl interpreter global
variable called "dom_id".  If the touched node doesn't have this tag, the
callback returns with no effect.  If the touched node also has a "value"
attribute tag (as with a HTML SELECT dropdown menu button), the value of that
tag is stored in a global variable called "dom_value".

After the DOM node's values are stored in the Tcl interpreter, a procedure in
the global namespace called "tksurf_callback" is called.  The default version of
this procedure loaded with the tksurf package is empty and does nothing.  A
package developer can define and re-define this procedure as desired.

A simple package called "tksurfdemo" is included.  When the package is loaded,
the tksurf browser window is launched with a simple HTML file containing a
SELECT dropdown menu button.  Each time the dropdown is touched and a different
option is selected, a new page corresponding to that option is loaded via a call
to the procedure "tksurf_callback" which is defined when the demo package is
loaded.  The demo package code is in the file
"/assets/tksurf/tm/tksurfdemo-0.1.tm".

MDD: Please let me know about any bugs you find with the tksurf package.