No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

admin.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. # -*- coding: utf-8 -*-
  2. from ...exceptions import *
  3. from .base import get_response
  4. from lodel.leapi.exceptions import *
  5. from lodel import logger
  6. from ...client import WebUiClient
  7. import leapi_dyncode as dyncode
  8. import warnings
  9. from lodel.leapi.datahandlers.base_classes import MultipleRef
  10. LIST_SEPARATOR = ','
  11. ##@brief These functions are called by the rules defined in ../urls.py
  12. ## To administrate the instance of the editorial model
  13. ##@brief Controller's function to redirect on the home page of the admin
  14. # @param request : the request (get or post)
  15. # @note the response is given in a html page called in get_response_function
  16. def index_admin(request):
  17. # We have to be identified to admin the instance
  18. # temporary, the acl will be more restrictive
  19. #if WebUiClient.is_anonymous():
  20. # return get_response('users/signin.html')
  21. return get_response('admin/admin.html')
  22. ##@brief Controller's function to update an object of the editorial model
  23. # @param request : the request (get or post)
  24. # @note the response is given in a html page (in templates/admin) called in get_response_function
  25. def admin_update(request):
  26. # We have to be identified to admin the instance
  27. # temporary, the acl will be more restrictive
  28. #if WebUiClient.is_anonymous():
  29. # return get_response('users/signin.html')
  30. msg=''
  31. # If the form has been submitted
  32. if request.method == 'POST':
  33. error = None
  34. datas = list()
  35. classname = request.form['classname']
  36. logger.warning('Composed uids broken here')
  37. uid = request.form['uid']
  38. try:
  39. target_leo = dyncode.Object.name2class(classname)
  40. except LeApiError:
  41. classname = None
  42. if classname is None or target_leo.is_abstract():
  43. raise HttpException(400, custom = "Bad classname given")
  44. leo_to_update = target_leo.get_from_uid(uid)
  45. errors = dict()
  46. for fieldname, value in request.form.items():
  47. #We want to drop 2 input named 'classname' and 'uid'
  48. if len(fieldname) > 12:
  49. #Other input names are : field_input_FIELDNAME
  50. #Extract the fieldname
  51. fieldname = fieldname[12:]
  52. try:
  53. dh = leo_to_update.data_handler(fieldname)
  54. except NameError as e:
  55. errors[fieldname] = e
  56. continue
  57. #Multiple ref list preparation
  58. if issubclass(dh.__class__, MultipleRef):
  59. value=[spl for spl in [
  60. v.strip() for v in value.split(LIST_SEPARATOR)]
  61. if len(spl) > 0]
  62. try:
  63. leo_to_update.set_data(fieldname, value)
  64. except Exception as e:
  65. errors[fieldname] = e
  66. continue
  67. if len(errors) > 0:
  68. custom_msg = '<h1>Errors in datas</h1><ul>'
  69. for fname, error in errors.items():
  70. custom_msg += '<li>%s : %s</li>' % (
  71. fname, error)
  72. custom_msg += '</ul>'
  73. raise HttpException(400, custom = custom_msg)
  74. try:
  75. leo_to_update.update()
  76. except Exception as e:
  77. raise HttpException(
  78. 500, custom = "Something goes wrong during update : %s" % e)
  79. # Display of the form with the object's values to be updated
  80. if 'classname' in request.GET:
  81. # We need the class of the object to update
  82. classname = request.GET['classname']
  83. if len(classname) > 1:
  84. raise HttpException(400)
  85. classname = classname[0]
  86. try:
  87. target_leo = dyncode.Object.name2class(classname)
  88. except LeApiError:
  89. # classname = None
  90. raise HttpException(400)
  91. logger.warning('Composed uids broken here')
  92. uid_field = target_leo.uid_fieldname()[0]
  93. # We need the uid of the object
  94. test_valid = 'lodel_id' in request.GET \
  95. and len(request.GET['lodel_id']) == 1
  96. if test_valid:
  97. try:
  98. dh = target_leo.field(uid_field)
  99. # we cast the uid extrated form the request to the adequate type
  100. # given by the datahandler of the uidfield's datahandler
  101. lodel_id = dh.cast_type(request.GET['lodel_id'][0])
  102. except (ValueError, TypeError):
  103. test_valid = False
  104. if not test_valid:
  105. raise HttpException(400)
  106. else:
  107. # Check if the object actually exists
  108. # We get it from the database
  109. query_filters = list()
  110. query_filters.append((uid_field,'=',lodel_id))
  111. obj = target_leo.get(query_filters)
  112. if len(obj) == 0:
  113. raise HttpException(404)
  114. return get_response('admin/admin_edit.html', target=target_leo, lodel_id =lodel_id)
  115. ##@brief Controller's function to create an object of the editorial model
  116. # @param request : the request (get or post)
  117. # @note the response is given in a html page (in templates/admin) called in get_response_function
  118. def admin_create(request):
  119. # We have to be identified to admin the instance
  120. # temporary, the acl will be more restrictive
  121. #if WebUiClient.is_anonymous():
  122. # return get_response('users/signin.html')
  123. classname = None
  124. # If the form has been submitted
  125. if request.method == 'POST':
  126. error = None
  127. datas = list()
  128. classname = request.form['classname']
  129. try:
  130. target_leo = dyncode.Object.name2class(classname)
  131. except LeApiError:
  132. classname = None
  133. if classname is None or target_leo.is_abstract():
  134. raise HttpException(400)
  135. fieldnames = target_leo.fieldnames()
  136. fields = dict()
  137. for in_put, in_value in request.form.items():
  138. # The classname is handled by the datasource, we are not allowed to modify it
  139. # both are hidden in the form, to identify the object here
  140. if in_put != 'classname' and in_value != '':
  141. dhl = target_leo.data_handler(in_put[12:])
  142. if dhl.is_reference() and in_value != '' and not dhl.is_singlereference():
  143. logger.info(in_value)
  144. in_value.replace(" ","")
  145. in_value=in_value.split(',')
  146. in_value=list(in_value)
  147. fields[in_put[12:]] = in_value
  148. if in_value == '':
  149. fields[in_put[12:]] = None
  150. # Insertion in the database of the values corresponding to a new object
  151. new_uid = target_leo.insert(fields)
  152. # reurn to the form with a confirmation or error message
  153. if not new_uid is None:
  154. msg = 'Successfull creation';
  155. else:
  156. msg = 'Oops something wrong happened...object not saved'
  157. return get_response('admin/admin_create.html', target=target_leo, msg = msg)
  158. # Display of an empty form
  159. if 'classname' in request.GET:
  160. # We need the class to create an object in
  161. classname = request.GET['classname']
  162. if len(classname) > 1:
  163. raise HttpException(400)
  164. classname = classname[0]
  165. try:
  166. target_leo = dyncode.Object.name2class(classname)
  167. except LeApiError:
  168. classname = None
  169. if classname is None or target_leo.is_abstract():
  170. raise HttpException(400)
  171. return get_response('admin/admin_create.html', target=target_leo)
  172. ##@brief Controller's function to delete an object of the editorial model
  173. # @param request : the request (get)
  174. # @note the response is given in a html page (in templates/admin) called in get_response_function
  175. def admin_delete(request):
  176. # We have to be identified to admin the instance
  177. # temporary, the acl will be more restrictive
  178. #if WebUiClient.is_anonymous():
  179. # return get_response('users/signin.html')
  180. classname = None
  181. if 'classname' in request.GET:
  182. # We need the class to delete an object in
  183. classname = request.GET['classname']
  184. if len(classname) > 1:
  185. raise HttpException(400)
  186. classname = classname[0]
  187. try:
  188. target_leo = dyncode.Object.name2class(classname)
  189. except LeApiError:
  190. # classname = None
  191. raise HttpException(400)
  192. logger.warning('Composed uids broken here')
  193. uid_field = target_leo.uid_fieldname()[0]
  194. # We also need the uid of the object to delete
  195. test_valid = 'lodel_id' in request.GET \
  196. and len(request.GET['lodel_id']) == 1
  197. if test_valid:
  198. try:
  199. dh = target_leo.field(uid_field)
  200. # we cast the uid extrated form the request to the adequate type
  201. # given by the datahandler of the uidfield's datahandler
  202. lodel_id = dh.cast_type(request.GET['lodel_id'][0])
  203. except (ValueError, TypeError):
  204. test_valid = False
  205. if not test_valid:
  206. raise HttpException(400)
  207. else:
  208. query_filters = list()
  209. query_filters.append((uid_field,'=',lodel_id))
  210. nb_deleted = target_leo.delete_bundle(query_filters)
  211. if nb_deleted == 1:
  212. msg = 'Object successfully deleted';
  213. else:
  214. msg = 'Oops something wrong happened...object still here'
  215. return get_response('admin/admin_delete.html', target=target_leo, lodel_id =lodel_id, msg = msg)
  216. def admin_classes(request):
  217. # We have to be identified to admin the instance
  218. # temporary, the acl will be more restrictive
  219. #if WebUiClient.is_anonymous():
  220. # return get_response('users/signin.html')
  221. return get_response('admin/list_classes_admin.html', my_classes = dyncode.dynclasses)
  222. def create_object(request):
  223. # We have to be identified to admin the instance
  224. # temporary, the acl will be more restrictive
  225. #if WebUiClient.is_anonymous():
  226. # return get_response('users/signin.html')
  227. return get_response('admin/list_classes_create.html', my_classes = dyncode.dynclasses)
  228. def delete_object(request):
  229. # We have to be identified to admin the instance
  230. # temporary, the acl will be more restrictive
  231. #if WebUiClient.is_anonymous():
  232. # return get_response('users/signin.html')
  233. return get_response('admin/list_classes_delete.html', my_classes = dyncode.dynclasses)
  234. def admin_class(request):
  235. # We have to be identified to admin the instance
  236. # temporary, the acl will be more restrictive
  237. #if WebUiClient.is_anonymous():
  238. # return get_response('users/signin.html')
  239. # We need the class we'll list to select the object to edit
  240. if 'classname' in request.GET:
  241. classname = request.GET['classname']
  242. if len(classname) > 1:
  243. raise HttpException(400)
  244. classname = classname[0]
  245. try:
  246. target_leo = dyncode.Object.name2class(classname)
  247. except LeApiError:
  248. classname = None
  249. if classname is None or target_leo.is_abstract():
  250. raise HttpException(400)
  251. return get_response('admin/show_class_admin.html', target=target_leo)
  252. def delete_in_class(request):
  253. # We have to be identified to admin the instance
  254. # temporary, the acl will be more restrictive
  255. #if WebUiClient.is_anonymous():
  256. # return get_response('users/signin.html')
  257. # We need the class we'll list to select the object to delete
  258. if 'classname' in request.GET:
  259. classname = request.GET['classname']
  260. if len(classname) > 1:
  261. raise HttpException(400)
  262. classname = classname[0]
  263. try:
  264. target_leo = dyncode.Object.name2class(classname)
  265. except LeApiError:
  266. classname = None
  267. if classname is None or target_leo.is_abstract():
  268. raise HttpException(400)
  269. return get_response('admin/show_class_delete.html', target=target_leo)
  270. def admin(request):
  271. # We have to be identified to admin the instance
  272. # temporary, the acl will be more restrictive
  273. #if WebUiClient.is_anonymous():
  274. # return get_response('users/signin.html')
  275. return get_response('admin/admin.html')
  276. def search_object(request):
  277. if request.method == 'POST':
  278. classname = request.POST['classname']
  279. searchstring = request.POST['searchstring']
  280. try:
  281. target_leo = dyncode.Object.name2class(classname)
  282. except LeApiError:
  283. raise HttpException(400)
  284. # TODO The get method must be implemented here
  285. return get_response('admin/admin_search.html', my_classes = dyncode.dynclasses)