view mamba/forest.py @ 550:91e1a95343b2

Add option to inform CIA of new levels.
author Simon Cross <hodgestar@gmail.com>
date Tue, 20 Sep 2011 17:29:38 +0200
parents 0c5853bb7a14
children 16344424dfcc
line wrap: on
line source

"""Where mamba's hang out with each other."""

from werkzeug.utils import secure_filename
from flask import Flask, request, abort

from datetime import datetime
import xmlrpclib
import time
import os
import sys

app = Flask(__name__)
app.config['LEVEL_FOLDER'] = None  # set later
app.config['CIA_PROJECT'] = None  # set to activate CIA sending


def path(ctype):
    if ctype == "curated":
        return os.path.join(app.config['LEVEL_FOLDER'], 'curated')
    elif ctype == "uncurated":
        return os.path.join(app.config['LEVEL_FOLDER'], 'uncurated')
    abort(404, "Not found")


def list_levels(folder):
    endl = len(".txt")
    files = [x[:-endl] for x in os.listdir(folder)
             if not x.startswith('.') and x.endswith('.txt')]
    return "\n".join(files)


@app.route("/<ctype>/index")
def index(ctype):
    ctype = path(ctype)
    return list_levels(ctype)


@app.route("/<ctype>/level/<levelname>")
def level(ctype, levelname):
    ctype = path(ctype)
    levelname = "%s.txt" % secure_filename(levelname)
    levelpath = os.path.join(ctype, levelname)
    if not os.path.isfile(levelpath):
        abort(404, "Level not found. Hsss.")
    with open(levelpath) as level:
        return level.read()


@app.route("/save/<levelname>", methods=['GET', 'POST'])
def save(levelname):
    ts = datetime.now().strftime("%Y%m%d.%H%M%S")
    levelname = "%s.%s.txt" % (secure_filename(levelname), ts)
    levelpath = os.path.join(path("uncurated"), levelname)
    if request.method == 'POST':
        if os.path.exists(levelpath):
            abort(409, "Mamba already resident.")
        leveldata = request.form['data'].encode('ascii')
        with open(levelpath, 'w') as level:
            level.write(leveldata)
        inform_cia(levelname, "New level uploaded.", branch="uncurated")
        return "Ssss."
    else:
        abort(405, "Post levels here. Hsss.")


MAMBA_VERSION = "0.1"
MAMBA_URL = "https://ctpug.org.za/hg/mamba"
CIA_URL = "http://cia.navi.cx"
CIA_MSG_TEMPLATE = """
<message
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="schema.xsd">
   <generator>
       <name>Mutable Mamba Level Server</name>
       <version>%(mamba_version)s</version>
       <url>%(mamba_url)s</url>
   </generator>
   <source>
       <project>%(project)s</project>
       <module>%(module)s</module>
       <branch>%(branch)s</branch>
   </source>
   <timestamp>
       %(timestamp)d
   </timestamp>
   <body>
       <commit>
           <revision>%(revision)s</revision>
           <author>%(author)s</author>
           <files>
               <file>%(file)s</file>
           </files>
           <log>
               %(log)s
           </log>
       </commit>
   </body>
</message>
"""


def inform_cia(filename, log, branch='uncurated'):
    if app.config['CIA_PROJECT'] is None:
        return
    msg = CIA_MSG_TEMPLATE % {
        'mamba_version': MAMBA_VERSION,
        'mamba_url': MAMBA_URL,
        'project': app.config['CIA_PROJECT'],
        'module': 'level-server',
        'branch': branch,
        'timestamp': int(time.time()),
        'revision': '0',
        'author': 'unknown',
        'file': filename,
        'log': log,
        }
    srv = xmlrpclib.Server(CIA_URL)
    srv.hub.deliver(msg)


if __name__ == "__main__":
    if len(sys.argv) not in (3, 4):
        print ("Usage: python -m mamba.forest <port> <level folder>"
               " [<cia project>]")
        sys.exit(1)

    host = '0.0.0.0'
    port = int(sys.argv[1])
    level_folder = sys.argv[2]
    for ctype in ("curated", "uncurated"):
        folder = os.path.join(level_folder, ctype)
        if not os.path.exists(folder):
            os.makedirs(folder)
        if not os.path.isdir(folder):
            print "Level folder must be a folder."
            sys.exit(1)
    cia_project = sys.argv[3] if len(sys.argv) > 3 else None

    app.config['LEVEL_FOLDER'] = level_folder
    app.config['CIA_PROJECT'] = cia_project
    # app.debug = True
    app.run(host=host, port=port)