modelverse.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. import urllib
  2. import urllib2
  3. import json
  4. import random
  5. from urllib2 import URLError
  6. import sys
  7. # Bind to the compiler
  8. sys.path.append("../interface/HUTN")
  9. from hutn_compiler.compiler import main as do_compile
  10. # Helper functions and configuration: do not use yourself!
  11. taskname = random.random()
  12. address = None
  13. last_output = None
  14. mode = 0
  15. def _input(value):
  16. # Ugly json encoding of primitives
  17. if isinstance(value, type([])):
  18. value = json.dumps(value)
  19. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": value, "taskname": taskname}))).read()
  20. else:
  21. value = json.dumps(value)
  22. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": taskname}))).read()
  23. def _input_raw(value, taskname):
  24. # Ugly json encoding of primitives
  25. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": taskname}))).read()
  26. def _compile_AL(code):
  27. # Compile an action language file and send the compiled code
  28. code_fragments = code.split("\n")
  29. code_fragments = [i for i in code_fragments if i.strip() != ""]
  30. code_fragments = [i.replace(" ", "\t") for i in code_fragments]
  31. initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
  32. code_fragments = [i[initial_tabs:] for i in code_fragments]
  33. code_fragments.append("")
  34. code = "\n".join(code_fragments)
  35. with open("__constraint.alc", "w") as f:
  36. f.write(code)
  37. f.flush()
  38. _input(do_compile("__constraint.alc", "../interface/HUTN/grammars/actionlanguage.g", "CS"))
  39. def _compile_model(code):
  40. # Compile a model and send the compiled graph
  41. # First change multiple spaces to a tab
  42. code_fragments = code.split("\n")
  43. code_fragments = [i for i in code_fragments if i.strip() != ""]
  44. code_fragments = [i.replace(" ", "\t") for i in code_fragments]
  45. initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
  46. code_fragments = [i[initial_tabs:] for i in code_fragments]
  47. code_fragments.append("")
  48. code = "\n".join(code_fragments)
  49. with open("__model.mvc", "w") as f:
  50. f.write(code)
  51. f.flush()
  52. _input(do_compile("__model.mvc", "../interface/HUTN/grammars/modelling.g", "M") + ["exit"])
  53. def _output():
  54. try:
  55. global last_output
  56. last_output = json.loads(urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "taskname": taskname}))).read())
  57. return last_output
  58. except:
  59. raise UnknownError()
  60. def _last_output():
  61. return last_output
  62. # Exceptions
  63. class ModelverseException(Exception):
  64. pass
  65. class UnknownError(ModelverseException):
  66. pass
  67. class UnknownIdentifier(ModelverseException):
  68. pass
  69. class UnknownType(ModelverseException):
  70. pass
  71. class UnsupportedValue(ModelverseException):
  72. pass
  73. class CompilationError(ModelverseException):
  74. pass
  75. class NoSuchAttribute(ModelverseException):
  76. pass
  77. class UnknownModel(ModelverseException):
  78. pass
  79. class ConnectionError(ModelverseException):
  80. pass
  81. class ModelExists(ModelverseException):
  82. pass
  83. class PermissionDenied(ModelverseException):
  84. pass
  85. class InvalidMode(ModelverseException):
  86. pass
  87. # Main MvC operations
  88. def init(address_param="http://localhost:8001"):
  89. """Starts up the connection to the Modelverse."""
  90. # return None
  91. # raises ConnectionError
  92. # raises UnknownError
  93. # raises InvalidMode
  94. global mode
  95. if mode != 0:
  96. raise InvalidMode()
  97. global address
  98. address = address_param
  99. try:
  100. _input_raw('"%s"' % taskname, "task_manager")
  101. mode = 1
  102. except URLError as e:
  103. raise ConnectionError(e.reason)
  104. def login(username, password):
  105. """Log in an existing user."""
  106. # return None
  107. # raises UnknownError
  108. # raises PermissionDenied
  109. global mode
  110. if mode != 1:
  111. raise InvalidMode()
  112. _input(username)
  113. _input(password)
  114. while (_output() != "Ready for command..."):
  115. pass
  116. mode = 2
  117. def register(username, password):
  118. """Register a new user."""
  119. # return None
  120. # raises UnknownError
  121. # raises UserExists
  122. global mode
  123. if mode != 1:
  124. raise InvalidMode()
  125. _input(username)
  126. _input(password)
  127. _input(password)
  128. while (_output() != "Ready for command..."):
  129. pass
  130. mode = 2
  131. def model_add(model_name, metamodel_name, model_code):
  132. """Instantiate a new model."""
  133. # return None
  134. # raises UnknownModel
  135. # raises ModelExists
  136. # raises UnknownError
  137. # raises PermissionDenied
  138. # raises CompilationError
  139. if mode != 2:
  140. raise InvalidMode()
  141. _input("model_add")
  142. _output()
  143. _output()
  144. _input(metamodel_name)
  145. if _output() == "Model name?":
  146. _input(model_name)
  147. if _output() == "Waiting for model constructors...":
  148. try:
  149. _compile_model(model_code)
  150. except Exception:
  151. raise CompilationError()
  152. while (_output() != "Ready for command..."):
  153. print(_last_output())
  154. pass
  155. else:
  156. raise ModelExists()
  157. elif _last_output() == "Could not find type model!":
  158. raise UnknownModel()
  159. elif _last_output() == "Permission denied":
  160. raise PermissionDenied()
  161. def model_modify(model_name):
  162. """Modify an existing model."""
  163. # return is_write
  164. # raises UnknownModel
  165. # raises PermissionDenied
  166. # raises UnknownError
  167. global mode
  168. if mode != 2:
  169. raise InvalidMode()
  170. _input("model_modify")
  171. _output()
  172. _input(model_name)
  173. if _output() == "Permission denied":
  174. raise PermissionDenied()
  175. elif _last_output() == "Could not find model!":
  176. raise UnknownModel()
  177. elif _last_output() == "Model loaded, ready for commands!":
  178. mode = 3
  179. if ("r/w" in _output()):
  180. write = True
  181. else:
  182. write = False
  183. while (_output() != "Please give your command."):
  184. pass
  185. return write
  186. def model_list():
  187. """List all models."""
  188. # return [(model1, metamodel1), (model2, metamodel2), ...]
  189. # raises UnknownError
  190. if mode != 2:
  191. raise InvalidMode()
  192. _input("model_list")
  193. lst = []
  194. while (_output() != "Ready for command..."):
  195. v = _last_output()
  196. m, mm = v.split(":")
  197. m.strip()
  198. mm.strip()
  199. lst.append((m, mm))
  200. return lst
  201. def model_list_full():
  202. """List full information on all models."""
  203. # return [(model1, metamodel1, owner1, group1, permissions1), (model2, metamodel2, owner2, group2, permissions2), ...]
  204. # raises UnknownError
  205. if mode != 2:
  206. raise InvalidMode()
  207. _input("model_list_full")
  208. lst = []
  209. while (_output() != "Ready for command..."):
  210. v = _last_output()
  211. m, mm = v.split(":")
  212. m.strip()
  213. mm.strip()
  214. perm, own, grp, m = m.split(" ")
  215. lst.append((m, mm, own, grp, perm))
  216. return lst
  217. def model_overwrite(model_name, new_model):
  218. """Upload a new model and overwrite an existing model."""
  219. # return None
  220. # raises UnknownModel
  221. # raises PermissionDenied
  222. # raises CompilationError
  223. # raises UnknownError
  224. if mode != 2:
  225. raise InvalidMode()
  226. _input("model_overwrite")
  227. _input(model_name)
  228. _compile_model(new_model)
  229. def user_logout():
  230. """Log out the current user. A new login will be required afterwards."""
  231. # return None
  232. # raises UnknownException
  233. global mode
  234. if mode != 2:
  235. raise InvalidMode()
  236. _input("exit")
  237. mode = 1
  238. def user_delete():
  239. """Removes the current user. A new login will be required afterwards."""
  240. # return None
  241. # raises UnknownException
  242. global mode
  243. if mode != 2:
  244. raise InvalidMode()
  245. _input("self-destruct")
  246. mode = 1
  247. # Actual operations on the model
  248. def element_list():
  249. """Return a list of all IDs and the type of the element"""
  250. # return [(name1, type1), (name2, type2), ...]
  251. # raises UnknownError
  252. if mode != 3:
  253. raise InvalidMode()
  254. _input("list")
  255. lst = []
  256. _output()
  257. while (_output() != "Please give your command."):
  258. v = _last_output()
  259. m, mm = v.split(":")
  260. m.strip()
  261. mm.strip()
  262. lst.append((m, mm))
  263. return lst
  264. def types():
  265. """Return a list of all types usable in the model"""
  266. # return [type1, type2, ...]
  267. # raises UnknownError
  268. if mode != 3:
  269. raise InvalidMode()
  270. _input("types")
  271. lst = []
  272. while (_output() != "Ready for command..."):
  273. v = _last_output()
  274. m, mm = v.split(":")
  275. m.strip()
  276. lst.append(m)
  277. return lst
  278. def read(ID):
  279. """Return a tuple of information on the element: its type and source/target (None if not an edge)"""
  280. # return (type, (source, target))
  281. # raises UnknownError
  282. # raises UnknownIdentifier
  283. if mode != 3:
  284. raise InvalidMode()
  285. _input("read")
  286. _input(ID)
  287. _output()
  288. t = _output().split(":")[1].strip()
  289. if (not _output().startswith("Source:")):
  290. rval = (t, None)
  291. else:
  292. src = _last_output().split(":")[1].strip()
  293. trg = _output().split(":")[1].strip()
  294. rval = (t, (src, trg))
  295. while (_output() != "Ready for command..."):
  296. pass
  297. return rval
  298. def read_attrs(ID):
  299. """Return a dictionary of attribute value pairs"""
  300. # return {attr1: value1, attr2: value2, ...}
  301. # raises UnknownError
  302. if mode != 3:
  303. raise InvalidMode()
  304. _input("read")
  305. _input(ID)
  306. rval = {}
  307. while (_output() != "Attributes:"):
  308. pass
  309. while (_output() != "Ready for command..."):
  310. r = _last_output()
  311. key, value = r.split(":")
  312. _, value = value.split("=")
  313. key.strip()
  314. value.strip()
  315. rval[key] = value
  316. return rval
  317. def instantiate(typename, edge=None, ID=""):
  318. """Create a new instance of the specified typename, between the selected elements (if not None), and with the provided ID (if any)"""
  319. # return instantiated_ID
  320. # raises UnknownError
  321. # raises UnknownType
  322. # raises UnknownIdentifier
  323. if mode != 3:
  324. raise InvalidMode()
  325. _input("instantiate")
  326. _input(typename)
  327. _input(ID)
  328. if (edge is not None):
  329. _input(edge[0])
  330. _input(edge[1])
  331. def delete(ID):
  332. """Delete the element with the given ID"""
  333. # return None
  334. # raises UnknownError
  335. # raises UnknownIdentifier
  336. if mode != 3:
  337. raise InvalidMode()
  338. _input("delete")
  339. _input(ID)
  340. def attr_assign(ID, attr, value):
  341. """Assign a value to an attribute"""
  342. # return None
  343. # raises UnknownError
  344. # raises UnknownIdentifier
  345. # raises NoSuchAttribute
  346. # raises UnsupportedValue
  347. if mode != 3:
  348. raise InvalidMode()
  349. _input("attr_modify")
  350. _input(ID)
  351. _input(attr)
  352. _input(value)
  353. def attr_assign_code(ID, attr, code):
  354. """Assign a piece of Action Language code to the attribute"""
  355. # return None
  356. # raises UnknownError
  357. # raises UnknownIdentifier
  358. # raises NoSuchAttribute
  359. # raises UnsupportedValue
  360. if mode != 3:
  361. raise InvalidMode()
  362. _input("attr_modify")
  363. _input(ID)
  364. _input(attr)
  365. _compile_AL(code)
  366. def upload(new_model):
  367. """Overwrite the current model with the provided model"""
  368. # return None
  369. # raises UnknownError
  370. # raises CompilationError
  371. if mode != 3:
  372. raise InvalidMode()
  373. _input("upload")
  374. _compile_model(new_model)
  375. def read_outgoing(ID, typename):
  376. """Returns a list of all outgoing associations of a specific type ("" = all)"""
  377. # return [name1, name2, ...]
  378. # raises UnknownError
  379. # raises UnknownIdentifier
  380. # raises UnknownType
  381. if mode != 3:
  382. raise InvalidMode()
  383. _input("read_outgoing")
  384. _input(ID)
  385. _input(typename)
  386. lst = []
  387. while (_output() != "Please give your command."):
  388. lst.append(_last_output())
  389. return lst
  390. def read_incoming(ID, typename):
  391. """Returns a list of all incoming associations of a specific type ("" = all)"""
  392. # return [name1, name2, ...]
  393. # raises UnknownError
  394. # raises UnknownIdentifier
  395. # raises UnknownType
  396. if mode != 3:
  397. raise InvalidMode()
  398. _input("read_incoming")
  399. _input(ID)
  400. _input(typename)
  401. lst = []
  402. while (_output() != "Please give your command."):
  403. lst.append(_last_output())
  404. return lst
  405. def model_exit():
  406. """Leave model modify mode."""
  407. # return None
  408. # raises UnknownError
  409. global mode
  410. if mode != 3:
  411. raise InvalidMode()
  412. _input("exit")
  413. mode = 2
  414. def transformation_add_MT_language():
  415. """Create a new Model Transformation language out of a set of metamodels."""
  416. raise NotImplementedError()
  417. def transformation_add_MT():
  418. """Create a new model transformation."""
  419. raise NotImplementedError()
  420. def transformation_add_AL():
  421. """Create a new action language fragment."""
  422. raise NotImplementedError()
  423. def transformation_add_MANUAL():
  424. """Create a new manual model operation."""
  425. raise NotImplementedError()
  426. def transformation_execute():
  427. """Execute an existing model operation."""
  428. raise NotImplementedError()
  429. def transformation_list():
  430. """List existing model operations."""
  431. raise NotImplementedError()
  432. def transformation_list_full():
  433. """List detailed information on model operations."""
  434. raise NotImplementedError()
  435. def transformation_detail():
  436. """List full details of a a model operation."""
  437. raise NotImplementedError()
  438. def transformation_RAMify():
  439. """Ramify an existing metamodel."""
  440. raise NotImplementedError()
  441. def process_execute():
  442. """Execute a process model."""
  443. raise NotImplementedError()
  444. def permission_modify():
  445. """Modify permissions of a model."""
  446. raise NotImplementedError()
  447. def permission_owner():
  448. """Modify the owning user of a model."""
  449. raise NotImplementedError()
  450. def permission_group():
  451. """Modify the owning group of a model."""
  452. raise NotImplementedError()
  453. def group_create():
  454. """Create a new group."""
  455. raise NotImplementedError()
  456. def group_delete():
  457. """Delete a group of which you are an owner."""
  458. raise NotImplementedError()
  459. def group_owner_add():
  460. """Add a new owning user to a group you own."""
  461. raise NotImplementedError()
  462. def group_owner_delete():
  463. """Delete an owning user to a group you own."""
  464. raise NotImplementedError()
  465. def group_join():
  466. """Add a new user to a group you own."""
  467. raise NotImplementedError()
  468. def group_kick():
  469. """Delete a user from a group you own."""
  470. raise NotImplementedError()
  471. def group_list():
  472. """List existing groups."""
  473. raise NotImplementedError()
  474. def admin_promote():
  475. """Promote a user to admin status."""
  476. raise NotImplementedError()
  477. def admin_demote():
  478. """Demote a user from admin status."""
  479. raise NotImplementedError()