new_contents: #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  
  # webvfx_generator.py
  # Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
  #
  # 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.
  
  # Import required modules
  import mlt
  import time
  import sys
  import tornado.ioloop
  import tornado.web
  import shutil
  import tempfile
  import os
  import os.path
  
  # Start the mlt system
  mlt.mlt_log_set_level(40) # verbose
  mlt.Factory.init()
  
  # Establish a pipeline
  profile = mlt.Profile("atsc_1080i_5994")
  #profile = mlt.Profile('square_ntsc_wide')
  profile.set_explicit(1)
  tractor = mlt.Tractor()
  tractor.set('eof', 'loop')
  playlist = mlt.Playlist()
  playlist.append(mlt.Producer(profile, 'color:'))
  
  # Setup the consumer
  consumer = 'decklink:0'
  if len(sys.argv) > 1:
    consumer = sys.argv[1]
  consumer = mlt.Consumer(profile, consumer)
  consumer.connect(playlist)
  #consumer.set("real_time", -2)
  consumer.start()
  
  def switch(resource):
    global playlist
    resource = resource
    playlist.lock()
    playlist.append(mlt.Producer(profile, str(resource)))
    playlist.remove(0)
    playlist.unlock()
  
  state = {}
  state['tempdir'] = None
  
  class MainHandler(tornado.web.RequestHandler):
    def get(self):
      resource = self.get_argument('url', None)
      if resource:
        global state
  
        self.write('Playing %s\n' % (resource))
        switch(resource)
  
        olddir = state['tempdir']
        if olddir:
          shutil.rmtree(olddir, True)
        state['tempdir'] = None
  
      else:
        self.write('''
  <p>POST a bunch of files to / to change the output.</p>
  <p>Or GET / with query string parameter "url" to display something from the network.</p>
  ''')
  
    def post(self):
      if len(self.request.files) == 0:
        self.write('POST a bunch of files to / to change the output')
      else:
        global state
        olddir = state['tempdir']
        resource = None
        state['tempdir'] = tempfile.mkdtemp()
        for key, items in self.request.files.iteritems():
          for item in items:
            path = os.path.dirname(key)
            fn = item.filename
            if path: 
              if not os.path.exists(os.path.join(state['tempdir'], path)):
                os.makedirs(os.path.join(state['tempdir'], path))
              fn = os.path.join(path, fn)
            fn = os.path.join(state['tempdir'], fn)
            if not path and fn.endswith('.html') or fn.endswith('.qml'):
              resource = fn
            with open(fn, 'w') as fo:
              fo.write(item.body)
            self.write("Uploaded %s\n" % (fn))
        if resource:
          self.write('Playing %s\n' % (resource))
          switch(resource)
        if olddir:
          shutil.rmtree(olddir, True)
  
  application = tornado.web.Application([
      (r"/", MainHandler),
  ])
  
  application.listen(8888)
  try:
    tornado.ioloop.IOLoop.instance().start()
  except:
    pass
  
  consumer.stop()
  if state['tempdir']:
    shutil.rmtree(state['tempdir'], True)
  
subject: Add python WebVfx-to-SDI web service.