|
@@ -1,319 +0,0 @@
|
|
|
-import urllib
|
|
|
-import urllib2
|
|
|
-import json
|
|
|
-import random
|
|
|
-from urllib2 import URLError
|
|
|
-import sys
|
|
|
-import time
|
|
|
-import threading
|
|
|
-
|
|
|
-COMPILER_PATH = "interface/HUTN"
|
|
|
-
|
|
|
-MODE_UNCONNECTED = 0
|
|
|
-MODE_UNAUTHORIZED = 1
|
|
|
-MODE_MODELLING = 2
|
|
|
-MODE_SERVICE = 6
|
|
|
-
|
|
|
-# Bind to the compiler (might have to update path manually!)
|
|
|
-sys.path.append(COMPILER_PATH)
|
|
|
-from hutn_compiler.compiler import main as do_compile
|
|
|
-
|
|
|
-# Exceptions
|
|
|
-class ModelverseException(Exception):
|
|
|
- pass
|
|
|
-
|
|
|
-class UnknownError(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class UnknownIdentifier(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class CompilationError(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class NoSuchAttribute(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class UnknownModel(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class ConnectionError(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class ModelExists(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class PermissionDenied(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class InvalidMode(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class InterfaceMismatch(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-class UnknownMetamodellingHierarchy(ModelverseException):
|
|
|
- pass
|
|
|
-
|
|
|
-# Helper functions and configuration: do not use yourself!
|
|
|
-taskname = None
|
|
|
-address = None
|
|
|
-last_output = None
|
|
|
-mode = MODE_UNCONNECTED
|
|
|
-prev_mode = None
|
|
|
-current_model = None
|
|
|
-registered_metamodels = {}
|
|
|
-
|
|
|
-def _check_type(value):
|
|
|
- if not isinstance(value, (int, long, float, str, unicode, bool)):
|
|
|
- raise UnsupportedValue("%s : %s" % (value, str(type(value))))
|
|
|
-
|
|
|
-def _check_type_list(value):
|
|
|
- if isinstance(value, list):
|
|
|
- [_check_type(i) for i in value]
|
|
|
- else:
|
|
|
- _check_type(value)
|
|
|
-
|
|
|
-def _goto_mode(new_mode, model_name=None):
|
|
|
- global mode
|
|
|
-
|
|
|
- if mode == new_mode:
|
|
|
- return
|
|
|
- else:
|
|
|
- # Go to a mode that we have no automatic transfer to: raise exception
|
|
|
- raise InvalidMode("Required mode: %s, current mode: %s" % (new_mode, mode))
|
|
|
-
|
|
|
-def _input(value, port=None):
|
|
|
- # Ugly json encoding of primitives
|
|
|
- if port is None:
|
|
|
- port = taskname
|
|
|
- if isinstance(value, type([])):
|
|
|
- value = json.dumps(value)
|
|
|
- urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": value, "taskname": port}))).read()
|
|
|
- else:
|
|
|
- value = json.dumps(value)
|
|
|
- #print("Set input: " + str(value))
|
|
|
- urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": port}))).read()
|
|
|
-
|
|
|
-def _input_raw(value, taskname):
|
|
|
- # Ugly json encoding of primitives
|
|
|
- urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": taskname}))).read()
|
|
|
-
|
|
|
-def _compile_AL(code):
|
|
|
- # Compile an action language file and send the compiled code
|
|
|
- code_fragments = code.split("\n")
|
|
|
- code_fragments = [i for i in code_fragments if i.strip() != ""]
|
|
|
- code_fragments = [i.replace(" ", "\t") for i in code_fragments]
|
|
|
- initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
|
|
|
- code_fragments = [i[initial_tabs:] for i in code_fragments]
|
|
|
- code_fragments.append("")
|
|
|
- code = "\n".join(code_fragments)
|
|
|
-
|
|
|
- with open(".code.alc", "w") as f:
|
|
|
- f.write(code)
|
|
|
- f.flush()
|
|
|
-
|
|
|
- compiled = do_compile(".code.alc", COMPILER_PATH + "/grammars/actionlanguage.g", "CS")
|
|
|
- return compiled
|
|
|
-
|
|
|
-def _compile_model(code):
|
|
|
- # Compile a model and send the compiled graph
|
|
|
- # First change multiple spaces to a tab
|
|
|
- code_fragments = code.split("\n")
|
|
|
- code_fragments = [i for i in code_fragments if i.strip() != ""]
|
|
|
- code_fragments = [i.replace(" ", "\t") for i in code_fragments]
|
|
|
- initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
|
|
|
- code_fragments = [i[initial_tabs:] for i in code_fragments]
|
|
|
- code_fragments.append("")
|
|
|
- code = "\n".join(code_fragments)
|
|
|
-
|
|
|
- with open(".model.mvc", "w") as f:
|
|
|
- f.write(code)
|
|
|
- f.flush()
|
|
|
-
|
|
|
- return do_compile(".model.mvc", COMPILER_PATH + "/grammars/modelling.g", "M")
|
|
|
-
|
|
|
-def _output(expected=None,port=None):
|
|
|
- if port is None:
|
|
|
- port = taskname
|
|
|
- try:
|
|
|
- global last_output
|
|
|
- last_output = json.loads(urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "taskname": port}))).read())
|
|
|
- #print("[OUT] %s" % last_output)
|
|
|
- except:
|
|
|
- raise UnknownError()
|
|
|
- if expected is not None and last_output != expected:
|
|
|
- raise InterfaceMismatch(_last_output(), expected)
|
|
|
- return last_output
|
|
|
-
|
|
|
-def _last_output():
|
|
|
- return last_output
|
|
|
-
|
|
|
-# Raise common exceptions
|
|
|
-def _handle_output(requested=None, split=None):
|
|
|
- value = _output()
|
|
|
- if value.startswith("Model exists: "):
|
|
|
- raise ModelExists(value.split(": ", 1)[1])
|
|
|
- elif value.startswith("Permission denied"):
|
|
|
- raise PermissionDenied(value.split(": ", 1)[1])
|
|
|
- elif value.startswith("Model not found: "):
|
|
|
- raise UnknownModel(value.split(": ", 1)[1])
|
|
|
- elif value.startswith("Element not found: "):
|
|
|
- raise UnknownIdentifier(value.split(": ", 1)[1])
|
|
|
- elif value.startswith("Element exists: "):
|
|
|
- raise ElementExists(value.split(": ", 1)[1])
|
|
|
- elif value.startswith("Attribute not found: "):
|
|
|
- raise NoSuchAttribute(value.split(": ", 1)[1])
|
|
|
- elif requested is not None and value.startswith(requested):
|
|
|
- if split is None:
|
|
|
- return value
|
|
|
- else:
|
|
|
- splitted = value.strip().split(split, 1)
|
|
|
- if len(splitted) == 1:
|
|
|
- return ""
|
|
|
- else:
|
|
|
- return splitted[1].rstrip()
|
|
|
- else:
|
|
|
- raise InterfaceMismatch(value)
|
|
|
-
|
|
|
-def _model_modify(model_name, metamodel_name):
|
|
|
- """Modify an existing model."""
|
|
|
- global mode
|
|
|
- global prev_mode
|
|
|
-
|
|
|
- if mode == MODE_MANUAL:
|
|
|
- prev_mode = MODE_MANUAL
|
|
|
- mode = MODE_MODIFY
|
|
|
- return None
|
|
|
-
|
|
|
- _goto_mode(MODE_MODELLING)
|
|
|
- prev_mode = MODE_MODELLING
|
|
|
-
|
|
|
- _input(["model_modify", model_name, metamodel_name])
|
|
|
- _handle_output("Success")
|
|
|
- global current_model
|
|
|
- current_model = model_name
|
|
|
- # Mode has changed
|
|
|
- mode = MODE_MODIFY
|
|
|
- _output("Model loaded, ready for commands!")
|
|
|
-
|
|
|
-def _model_exit():
|
|
|
- """Leave model modify mode."""
|
|
|
- global mode
|
|
|
- global prev_mode
|
|
|
-
|
|
|
- if prev_mode == MODE_MANUAL:
|
|
|
- mode = MODE_MANUAL
|
|
|
- return
|
|
|
-
|
|
|
- if mode != MODE_MODIFY:
|
|
|
- raise InvalidMode()
|
|
|
-
|
|
|
- _input("exit")
|
|
|
- _output("Success")
|
|
|
- mode = MODE_MODELLING
|
|
|
-
|
|
|
-def alter_context(model_name, metamodel_name):
|
|
|
- global registered_metamodels
|
|
|
- registered_metamodels[model_name] = metamodel_name
|
|
|
-
|
|
|
-# Main MvC operations
|
|
|
-def init(address_param="127.0.0.1:8001", timeout=20.0):
|
|
|
- """Starts up the connection to the Modelverse."""
|
|
|
- global mode
|
|
|
- global address
|
|
|
- global taskname
|
|
|
- address = "http://%s" % address_param
|
|
|
- start_time = time.time()
|
|
|
- taskname = random.random()
|
|
|
- while 1:
|
|
|
- try:
|
|
|
- _input_raw('"%s"' % taskname, "task_manager")
|
|
|
- mode = MODE_UNAUTHORIZED
|
|
|
- break
|
|
|
- except URLError as e:
|
|
|
- if time.time() - start_time > timeout:
|
|
|
- raise ConnectionError(e.reason)
|
|
|
- else:
|
|
|
- time.sleep(0.1)
|
|
|
-
|
|
|
-def login(username, password):
|
|
|
- """Log in a user, if user doesn't exist, it is created."""
|
|
|
- global mode
|
|
|
- _goto_mode(MODE_UNAUTHORIZED)
|
|
|
-
|
|
|
- _output("Log on as which user?")
|
|
|
- _input(username)
|
|
|
- if _output() == "Password for existing user?":
|
|
|
- _input(password)
|
|
|
- if _output() == "Welcome to the Model Management Interface v2.0!":
|
|
|
- _output("Use the 'help' command for a list of possible commands")
|
|
|
- _input("quiet")
|
|
|
- mode = MODE_MODELLING
|
|
|
- elif _last_output() == "Wrong password!":
|
|
|
- raise PermissionDenied()
|
|
|
- else:
|
|
|
- raise InterfaceMismatch(_last_output())
|
|
|
- elif _last_output() == "This is a new user: please give password!":
|
|
|
- _input(password)
|
|
|
- _output("Please repeat the password")
|
|
|
- _input(password)
|
|
|
- if _output() == "Passwords match!":
|
|
|
- _output("Welcome to the Model Management Interface v2.0!")
|
|
|
- _output("Use the 'help' command for a list of possible commands")
|
|
|
- _input("quiet")
|
|
|
- mode = MODE_MODELLING
|
|
|
- elif _last_output() == "Not the same password!":
|
|
|
- # We just sent the same password, so it should be identical, unless the interface changed
|
|
|
- raise InterfaceMismatch(_last_output())
|
|
|
- else:
|
|
|
- raise InterfaceMismatch(_last_output())
|
|
|
- else:
|
|
|
- raise InterfaceMismatch(_last_output())
|
|
|
-
|
|
|
-def service_register(name, function):
|
|
|
- """Register a function as a service with a specific name."""
|
|
|
-
|
|
|
- def service_process(port):
|
|
|
- while 1:
|
|
|
- thrd = threading.Thread(target=function, args=[service_get(port)])
|
|
|
- thrd.daemon = True
|
|
|
- thrd.start()
|
|
|
-
|
|
|
- global mode
|
|
|
- _goto_mode(MODE_MODELLING)
|
|
|
-
|
|
|
- _input(["service_register", name])
|
|
|
-
|
|
|
- # Now we are in service-mode
|
|
|
- mode = MODE_SERVICE
|
|
|
- port = _handle_output("Success: ", split=" ")
|
|
|
-
|
|
|
- # Process events in the background!
|
|
|
- threading.Thread(target=service_process, args=[port]).start()
|
|
|
-
|
|
|
-def service_stop():
|
|
|
- """Stop the currently executing process."""
|
|
|
- _goto_mode(MODE_SERVICE)
|
|
|
- _input("service_stop")
|
|
|
- _handle_output("Success")
|
|
|
-
|
|
|
- global mode
|
|
|
- mode = MODE_MODELLING
|
|
|
-
|
|
|
-def service_get(port):
|
|
|
- """Get the values on the specified port."""
|
|
|
- _goto_mode(MODE_SERVICE)
|
|
|
-
|
|
|
- return _output(port=port)
|
|
|
-
|
|
|
-def service_set(port, value):
|
|
|
- """Set a value on a specified port."""
|
|
|
- _check_type_list(value)
|
|
|
- _goto_mode(MODE_SERVICE)
|
|
|
-
|
|
|
- _input(value, port=port)
|
|
|
-
|
|
|
-def service_poll(port):
|
|
|
- """Checks whether or not the Modelverse side has any input ready to be processed."""
|
|
|
- raise NotImplementedError()
|