Tuesday, May 5, 2015

File Monitor

Factor has a cross-platform file-system change monitor which supports detecting changes to file names, attributes and contents under a specified directory.

There is some minor platform differences between Mac OS X, Windows, and Linux which may be worth looking at if you are building on top of the io.monitors vocabulary. I was curious about what kind of events are generated for various test-cases and built a small utility to experiment with it.

Some code to monitor for changed paths recursively in a directory and print each one out:

: watch-loop ( monitor -- )
    dup next-change path>> print flush watch-loop ;

: watch-directory ( path -- )
    [ t [ watch-loop ] with-monitor ] with-monitors ;

I've committed this as the file-monitor tool (with support for an optional command-line argument to specify which directory to monitor as well as printing the change descriptors). You can run it very simply:

factor -run=file-monitor [path]

An example session on Linux, monitoring some simple changes to files in /tmp:

$ factor -run=file-monitor /tmp &
Monitoring /tmp

$ touch /tmp/a
{ +add-file+ } /tmp/a
{ +add-file+ } /tmp/a
{ +modify-file+ } /tmp/a

$ echo "test" > /tmp/a
{ +modify-file+ } /tmp/a

$ rm /tmp/a
{ +remove-file+ } /tmp/a

Friday, May 1, 2015

File Server

Python has a neat feature that lets you serve files from the current directory.

# Python 2
python2 -m SimpleHTTPServer

# Python 3
python3 -m http.server

I always thought this was a quick and useful way to share files on a local network. Given that Factor has a HTTP Server, we should be able to implement this!

We already have support for serving static content and serving CGI scripts, so we can very simply implement a script to create and launch a HTTP server for the current directory (or the one specified on the command-line), logging HTTP connections to stdout.

This is available in the file-server vocabulary, now you can:

factor -run=file-server [--cgi] [path]

Currently, this defaults to serving files on port 8080 from all available network interfaces. In the future, it would be nice to add the ability to specify port and network interfaces to bind.