#!/usr/bin/python

# js_sender.py
#       --copyright--                   Copyright 2009 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       November 21, 2009       bar
#       November 24, 2009       bar     play with weird clock() function under vmware
#       December 1, 2009        bar     queue and handle a None at clear() time
#       December 6, 2009        bar     tell parent we're alive if he has a callback
#       December 7, 2009        bar     a way to stop it from outside
#       February 16, 2010       bar     extra quotes
#       November 29, 2011       bar     pyflake cleanup
#       --eodstamps--
##      \file
#
#
#       Inject an IFRAME for a given URL/path in to an HTML page.
#       The IFRAME constantly gets some javascript encapsulated in html from the server.
#       We provide that HTML after a timeout or when js needs be sent to the browser.
#
#       TODO:
#
#

import  Queue
import  re
import  time

import  tzlib


class   a_js_sender(object) :

    body_injection_re   = re.compile(r"(</body)", re.IGNORECASE)
    html_injection_re   = re.compile(r"(</html)", re.IGNORECASE)

    injection_html      = """\r\n<iframe style="visibility:hidden" src="%s" height="0" width="0"></iframe>\r\n"""

    control_html        = """<html><head>
                             <meta http-equiv="Content-type"  content="text/html" />
                             <meta http-equiv="Cache-control" content="no-store"  />
                             </head><body><script language="javascript"><!--

                             var    the_location    = location;

                             %s
                             if (parent.js_sender_active)
                             {
                                 parent.js_sender_active();
                             }
                             if (the_location)
                             {
                                 the_location.reload();
                             }
                             --></script></body></html>
                          """
    control_html        = tzlib.multiline_strip(control_html)


    def __init__(me, url) :

        me.timeout  = 19
        me.ihtml    = me.injection_html % ( url or "" )
        me.q        = Queue.Queue()         # js input queue



    def inject_into_html(me, html) :
        """ Put our IFRAME in to the given web page. """

        if  me.body_injection_re.search(html) :
            return(me.body_injection_re.sub(me.ihtml + r"\1", html, 1))

        if  me.html_injection_re.search(html) :
            return(me.html_injection_re.sub(me.ihtml + r"\1", html, 1))

        return(html + me.ihtml)



    def http_get(me) :
        """ Server calls this routine to get HTML (with js included) to send to the browser. """

        js          = ""
        t           = me.timeout
        st          = tzlib.elapsed_time()
        while True  :
            try     :
                # s   = me.q.get(True, t)
                s   = me.q.get_nowait()
                if  s  == None :
                    break;                              # we've been told to quit or whatever
                js += s + "\r\n"
                t   = 0
            except Queue.Empty :
                if  js or (tzlib.elapsed_time() - st >= t) :
                    break
                time.sleep(0.010)
            pass

        htm         = me.control_html % js

        return(htm.strip())



    def put_js(me, js) :
        """ Send the given js to the browser next chance we get. """

        me.q.put(js)



    def clear_js(me) :
        """ Forget any queued js. """

        while True :
            try :
                me.q.get_nowait()
            except Queue.Empty :
                break
            pass

        me.put_js(None)         # tell the getter to finish up now


    pass    # a_js_sender


##      Command line help string.
help_str    = """
%s

Injects an IFRAME in to a web page so the web page can be updated with .js code quickly at run time.

"""

#
#
#
if __name__ == '__main__' :

    import  os
    import  sys

    import  TZCommandLineAtFile


    program_name    = sys.argv.pop(0)
    TZCommandLineAtFile.expand_at_sign_command_line_files(sys.argv)


    if  tzlib.array_find(sys.argv, [ "--help", "-h", "-?", "/?", ] ) >= 0 :
        print help_str % ( os.path.basename(program_name), )
        sys.exit(254)


    me  = a_js_sender("/blah.htm")

    print "----------------------"
    print me.inject_into_html("<html><body>test page</body ></html>")
    print "----------------------"
    print "----------------------"
    print me.inject_into_html("<html><body>test page</html>")
    print "----------------------"
    print "----------------------"
    print me.inject_into_html("<html><body>test page")
    print "----------------------"
    print "----------------------"

    me.put_js("// 'parent' is the main page.\r\nx = 5;\r\n  parent.pass_x_to_main_page(x);")
    me.put_js("// Some more code\r\n")
    print me.http_get()

    print "----------------------"

#
#
#
# eof

