#!/usr/bin/python
#    This is a component of AXIS, a front-end for emc
#    Copyright 2008, Jeff Epler <jepler@unpythonic.net>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

"""\
axis-dropbox: Automatically open new or modified gcode files in axis

Make this file executable, rename it axis-dropbox and place it on your
$PATH.  Then put a line to load it in one of your .hal files:
    loadusr axis-dropbox

You may specify a list of directories to look in and a list of
extensions for gcode programs on the commandline.  First specify the
list of directories, then "--", then the list of extensions.  For
example:
    loadusr axis-dropbox ~/gcode ~/Desktop -- .ngc .g

If not specified, the directories default to
    ~/emc2/ncfiles ~/emc2/nc_files
and the extensions default to
    .ngc

A gcode file is only opened when it is "complete".  A "complete" file
ends with one of the following:
    "m2" newline
    "M2" newline
    "%"
    "%" newline
"""

import hal
import sys
# making this a hal component is one easy way to make sure it gets
# cleaned up when emc is shut down
h = hal.component(sys.argv[0])
h.ready()

import getopt
import os
import re
import time
import Tkinter

t = Tkinter.Tk(); t.wm_withdraw()

extensions = set(['.ngc'])
directories = ["~/emc2/ncfiles", "~/emc2/nc_files"]

def axis_open(filename):
    try:
        t.tk.call("send", "axis", "open_file_name", filename)
    except Tkinter.TclError, detail:
        print >>sys.stderr, "open failed: %s" % detail

def is_complete_file(filename):
    try:
        f = open(filename, "rU")
        sz = os.fstat(f.fileno()).st_size
        if sz > 100:
            f.seek(sz - 100)
        s = f.read().lower()
        print repr(s)
        return s.endswith("m2\n") or s.endswith("%") or s.endswith("%\n")
    except IOError:
        return False

modtimes = {}
def poll(first=False):
    result = []
    for d in directories:
        try:
            c = os.listdir(d)
        except os.error:
            continue
        for f in c:
            ext = os.path.splitext(f)[1]
            if ext not in extensions: continue
            filename = os.path.join(d, f)
            try:
                mtime = os.stat(filename).st_mtime
            except os.error:
                continue
            if not first:
                if (mtime > modtimes.get(filename, 0)
                        and is_complete_file(filename)):
                    result.append(filename)
            modtimes[filename] = mtime
    return result

args = sys.argv[1:]
if "--" in args:
    i = args.index("--")
    directories = args[:i] or directories
    extensions = args[i+1:]
else if args:
    directories = args

directories = [os.path.expanduser(d) for d in directories]
directories = [d for d in directories if os.path.isdir(d)]

poll(True)

try:
    while 1:
        time.sleep(.5)
        f = poll()
        if f:
            axis_open(f[0])
except KeyboardInterrupt:
    pass
