modelverse.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  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. def _consume_to_end():
  63. while (_output() not in ["Ready for command...", "Please give your command."]):
  64. pass
  65. # Exceptions
  66. class ModelverseException(Exception):
  67. pass
  68. class UnknownException(ModelverseException):
  69. pass
  70. class UnknownIdentifier(ModelverseException):
  71. pass
  72. class UnknownType(ModelverseException):
  73. pass
  74. class UnsupportedValue(ModelverseException):
  75. pass
  76. class CompilationError(ModelverseException):
  77. pass
  78. class NoSuchAttribute(ModelverseException):
  79. pass
  80. class UnknownModel(ModelverseException):
  81. pass
  82. class ConnectionError(ModelverseException):
  83. pass
  84. class ModelExists(ModelverseException):
  85. pass
  86. class PermissionDenied(ModelverseException):
  87. pass
  88. class InvalidMode(ModelverseException):
  89. pass
  90. # Main MvC operations
  91. def init(address_param="http://localhost:8001"):
  92. """Starts up the connection to the Modelverse."""
  93. # return None
  94. # raises ConnectionError
  95. # raises UnknownError
  96. # raises InvalidMode
  97. global mode
  98. if mode != 0:
  99. raise InvalidMode()
  100. global address
  101. address = address_param
  102. try:
  103. _input_raw('"%s"' % taskname, "task_manager")
  104. mode = 1
  105. except URLError as e:
  106. raise ConnectionError(e.reason)
  107. def login(username, password):
  108. """Log in an existing user."""
  109. # return None
  110. # raises UnknownError
  111. # raises PermissionDenied
  112. global mode
  113. if mode != 1:
  114. raise InvalidMode()
  115. _input(username)
  116. _input(password)
  117. _consume_to_end()
  118. mode = 2
  119. def register(username, password):
  120. """Register a new user."""
  121. # return None
  122. # raises UnknownError
  123. # raises UserExists
  124. global mode
  125. if mode != 1:
  126. raise InvalidMode()
  127. _input(username)
  128. _input(password)
  129. _input(password)
  130. _consume_to_end()
  131. mode = 2
  132. def model_add(model_name, metamodel_name, model_code=None):
  133. """Instantiate a new model."""
  134. # return None
  135. # raises UnknownModel
  136. # raises ModelExists
  137. # raises UnknownError
  138. # raises PermissionDenied
  139. # raises CompilationError
  140. if mode != 2:
  141. raise InvalidMode()
  142. _input("model_add")
  143. _output()
  144. _output()
  145. _input(metamodel_name)
  146. if _output() == "Model name?":
  147. _input(model_name)
  148. if _output() == "Waiting for model constructors...":
  149. try:
  150. if model_code == None:
  151. _input("exit")
  152. else:
  153. _compile_model(model_code)
  154. except Exception:
  155. raise CompilationError()
  156. _consume_to_end()
  157. else:
  158. _consume_to_end()
  159. raise ModelExists()
  160. elif _last_output() == "Could not find type model!":
  161. _consume_to_end()
  162. raise UnknownModel()
  163. elif _last_output() == "Permission denied":
  164. _consume_to_end()
  165. raise PermissionDenied()
  166. def model_modify(model_name):
  167. """Modify an existing model."""
  168. # return is_write
  169. # raises UnknownModel
  170. # raises PermissionDenied
  171. # raises UnknownError
  172. global mode
  173. if mode != 2:
  174. raise InvalidMode()
  175. _input("model_modify")
  176. _output()
  177. _input(model_name)
  178. if _output() == "Permission denied":
  179. _consume_to_end()
  180. raise PermissionDenied()
  181. elif _last_output() == "Could not find model!":
  182. _consume_to_end()
  183. raise UnknownModel()
  184. elif _last_output() == "Model loaded, ready for commands!":
  185. mode = 3
  186. if ("r/w" in _output()):
  187. write = True
  188. else:
  189. write = False
  190. _consume_to_end()
  191. return write
  192. else:
  193. _consume_to_end()
  194. raise UnknownException()
  195. def model_list():
  196. """List all models."""
  197. # return [(model1, metamodel1), (model2, metamodel2), ...]
  198. # raises UnknownError
  199. if mode != 2:
  200. raise InvalidMode()
  201. _input("model_list")
  202. lst = []
  203. while (_output() != "Ready for command..."):
  204. v = _last_output()
  205. m, mm = v.split(":")
  206. m = m.strip()
  207. mm = mm.strip()
  208. lst.append((m, mm))
  209. return lst
  210. def model_list_full():
  211. """List full information on all models."""
  212. # return [(model1, metamodel1, owner1, group1, permissions1), (model2, metamodel2, owner2, group2, permissions2), ...]
  213. # raises UnknownError
  214. if mode != 2:
  215. raise InvalidMode()
  216. _input("model_list_full")
  217. lst = []
  218. while (_output() != "Ready for command..."):
  219. v = _last_output()
  220. m, mm = v.split(":")
  221. m = m.strip()
  222. mm = mm.strip()
  223. perm, own, grp, m = m.split(" ")
  224. lst.append((m, mm, own, grp, perm))
  225. return lst
  226. def model_overwrite(model_name, new_model):
  227. """Upload a new model and overwrite an existing model."""
  228. # return None
  229. # raises UnknownModel
  230. # raises PermissionDenied
  231. # raises CompilationError
  232. # raises UnknownError
  233. if mode != 2:
  234. raise InvalidMode()
  235. _input("model_overwrite")
  236. _input(model_name)
  237. _compile_model(new_model)
  238. def user_logout():
  239. """Log out 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("exit")
  246. mode = 1
  247. def user_delete():
  248. """Removes the current user. A new login will be required afterwards."""
  249. # return None
  250. # raises UnknownException
  251. global mode
  252. if mode != 2:
  253. raise InvalidMode()
  254. _input("self-destruct")
  255. mode = 1
  256. # Actual operations on the model
  257. def element_list():
  258. """Return a list of all IDs and the type of the element"""
  259. # return [(name1, type1), (name2, type2), ...]
  260. # raises UnknownError
  261. if mode != 3:
  262. raise InvalidMode()
  263. _input("list")
  264. lst = []
  265. _output()
  266. while (_output() != "Please give your command."):
  267. v = _last_output()
  268. m, mm = v.split(":")
  269. m = m.strip()
  270. mm = mm.strip()
  271. lst.append((m, mm))
  272. return lst
  273. def types():
  274. """Return a list of all types usable in the model"""
  275. # return [type1, type2, ...]
  276. # raises UnknownError
  277. if mode != 3:
  278. raise InvalidMode()
  279. _input("types")
  280. _output()
  281. lst = []
  282. while (_output() != "Please give your command."):
  283. v = _last_output()
  284. m, mm = v.split(":")
  285. m = m.strip()
  286. lst.append(m)
  287. return lst
  288. def read(ID):
  289. """Return a tuple of information on the element: its type and source/target (None if not an edge)"""
  290. # return (type, (source, target))
  291. # raises UnknownError
  292. # raises UnknownIdentifier
  293. if mode != 3:
  294. raise InvalidMode()
  295. _input("read")
  296. _output()
  297. _input(ID)
  298. _output()
  299. if _last_output() == "Unknown element; aborting":
  300. _consume_to_end()
  301. raise UnknownIdentifier()
  302. else:
  303. t = _output().split(":")[1].strip()
  304. if (not _output().startswith("Source:")):
  305. rval = (t, None)
  306. else:
  307. src = _last_output().split(":")[1].strip()
  308. trg = _output().split(":")[1].strip()
  309. rval = (t, (src, trg))
  310. while (_output() != "Please give your command."):
  311. pass
  312. return rval
  313. def read_attrs(ID):
  314. """Return a dictionary of attribute value pairs"""
  315. # return {attr1: value1, attr2: value2, ...}
  316. # raises UnknownError
  317. # raises UnknownIdentifier
  318. if mode != 3:
  319. raise InvalidMode()
  320. _input("read")
  321. _output()
  322. _input(ID)
  323. _output()
  324. if _last_output() == "Unknown element; aborting":
  325. _consume_to_end()
  326. raise UnknownIdentifier()
  327. else:
  328. rval = {}
  329. while (_output() != "Attributes:"):
  330. pass
  331. while (_output() != "Please give your command."):
  332. r = _last_output()
  333. key, value = r.split(":")
  334. _, value = value.split("=")
  335. key = json.loads(key.strip())
  336. value = value.strip()
  337. value = None if value == "None" else json.loads(value)
  338. rval[key] = value
  339. return rval
  340. def instantiate(typename, edge=None, ID=""):
  341. """Create a new instance of the specified typename, between the selected elements (if not None), and with the provided ID (if any)"""
  342. # return instantiated_ID
  343. # raises UnknownError
  344. # raises UnknownType
  345. # raises UnknownIdentifier
  346. # raises NotAnEdge
  347. if mode != 3:
  348. raise InvalidMode()
  349. _input("instantiate")
  350. if (_output() == "Permission denied"):
  351. _consume_to_end()
  352. raise PermissionDenied()
  353. else:
  354. _input(typename)
  355. if (_output() == "Name of new element?"):
  356. _input(ID)
  357. if (_output() == "Element already exists; aborting"):
  358. _consume_to_end()
  359. raise ElementExists()
  360. if (edge is not None):
  361. if (_last_output() == "Source name?"):
  362. _input(edge[0])
  363. if (_output() != "Destination name?"):
  364. _consume_to_end()
  365. raise UnknownIdentifier()
  366. _input(edge[1])
  367. ID = _output()
  368. if (ID == "Unknown destination; aborting"):
  369. _consume_to_end()
  370. raise UnknownIdentifier()
  371. else:
  372. _consume_to_end()
  373. return ID
  374. else:
  375. _consume_to_end()
  376. raise NotAnEdge()
  377. else:
  378. ID = _last_output()
  379. _consume_to_end()
  380. return ID
  381. elif (_last_output() == "Permission denied"):
  382. _consume_to_end()
  383. raise PermissionDenied()
  384. elif (_last_output() == "Unknown type specified; aborting"):
  385. _consume_to_end()
  386. raise UnknownType()
  387. else:
  388. print(9)
  389. print(_last_output())
  390. def delete(ID):
  391. """Delete the element with the given ID"""
  392. # return None
  393. # raises UnknownError
  394. # raises UnknownIdentifier
  395. if mode != 3:
  396. raise InvalidMode()
  397. _input("delete")
  398. _input(ID)
  399. def attr_assign(ID, attr, value):
  400. """Assign a value to an attribute"""
  401. # return None
  402. # raises UnknownError
  403. # raises UnknownIdentifier
  404. # raises NoSuchAttribute
  405. # raises UnsupportedValue
  406. if mode != 3:
  407. raise InvalidMode()
  408. _input("attr_modify")
  409. _input(ID)
  410. _input(attr)
  411. _input(value)
  412. _consume_to_end()
  413. def attr_assign_code(ID, attr, code):
  414. """Assign a piece of Action Language code to the attribute"""
  415. # return None
  416. # raises UnknownError
  417. # raises UnknownIdentifier
  418. # raises NoSuchAttribute
  419. # raises UnsupportedValue
  420. if mode != 3:
  421. raise InvalidMode()
  422. _input("attr_modify")
  423. _input(ID)
  424. _input(attr)
  425. _compile_AL(code)
  426. def upload(new_model):
  427. """Overwrite the current model with the provided model"""
  428. # return None
  429. # raises UnknownError
  430. # raises CompilationError
  431. if mode != 3:
  432. raise InvalidMode()
  433. _input("upload")
  434. _compile_model(new_model)
  435. def read_outgoing(ID, typename):
  436. """Returns a list of all outgoing associations of a specific type ("" = all)"""
  437. # return [name1, name2, ...]
  438. # raises UnknownError
  439. # raises UnknownIdentifier
  440. # raises UnknownType
  441. if mode != 3:
  442. raise InvalidMode()
  443. _input("read_outgoing")
  444. _input(ID)
  445. _input(typename)
  446. lst = []
  447. while (_output() != "Please give your command."):
  448. lst.append(_last_output())
  449. return lst
  450. def read_incoming(ID, typename):
  451. """Returns a list of all incoming associations of a specific type ("" = all)"""
  452. # return [name1, name2, ...]
  453. # raises UnknownError
  454. # raises UnknownIdentifier
  455. # raises UnknownType
  456. if mode != 3:
  457. raise InvalidMode()
  458. _input("read_incoming")
  459. _input(ID)
  460. _input(typename)
  461. lst = []
  462. while (_output() != "Please give your command."):
  463. lst.append(_last_output())
  464. return lst
  465. def model_exit():
  466. """Leave model modify mode."""
  467. # return None
  468. # raises UnknownError
  469. global mode
  470. if mode != 3:
  471. raise InvalidMode()
  472. _input("exit")
  473. _consume_to_end()
  474. mode = 2
  475. def transformation_add_MT_language():
  476. """Create a new Model Transformation language out of a set of metamodels."""
  477. raise NotImplementedError()
  478. def transformation_add_MT():
  479. """Create a new model transformation."""
  480. raise NotImplementedError()
  481. def transformation_add_AL():
  482. """Create a new action language fragment."""
  483. raise NotImplementedError()
  484. def transformation_add_MANUAL():
  485. """Create a new manual model operation."""
  486. raise NotImplementedError()
  487. def transformation_execute():
  488. """Execute an existing model operation."""
  489. raise NotImplementedError()
  490. def transformation_list():
  491. """List existing model operations."""
  492. raise NotImplementedError()
  493. def transformation_list_full():
  494. """List detailed information on model operations."""
  495. raise NotImplementedError()
  496. def transformation_detail():
  497. """List full details of a a model operation."""
  498. raise NotImplementedError()
  499. def transformation_RAMify():
  500. """Ramify an existing metamodel."""
  501. raise NotImplementedError()
  502. def process_execute():
  503. """Execute a process model."""
  504. raise NotImplementedError()
  505. def permission_modify():
  506. """Modify permissions of a model."""
  507. raise NotImplementedError()
  508. def permission_owner():
  509. """Modify the owning user of a model."""
  510. raise NotImplementedError()
  511. def permission_group():
  512. """Modify the owning group of a model."""
  513. raise NotImplementedError()
  514. def group_create():
  515. """Create a new group."""
  516. raise NotImplementedError()
  517. def group_delete():
  518. """Delete a group of which you are an owner."""
  519. raise NotImplementedError()
  520. def group_owner_add():
  521. """Add a new owning user to a group you own."""
  522. raise NotImplementedError()
  523. def group_owner_delete():
  524. """Delete an owning user to a group you own."""
  525. raise NotImplementedError()
  526. def group_join():
  527. """Add a new user to a group you own."""
  528. raise NotImplementedError()
  529. def group_kick():
  530. """Delete a user from a group you own."""
  531. raise NotImplementedError()
  532. def group_list():
  533. """List existing groups."""
  534. raise NotImplementedError()
  535. def admin_promote():
  536. """Promote a user to admin status."""
  537. raise NotImplementedError()
  538. def admin_demote():
  539. """Demote a user from admin status."""
  540. raise NotImplementedError()