views.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #
  2. # BitBake Toaster Implementation
  3. #
  4. # Copyright (C) 2013 Intel Corporation
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License version 2 as
  8. # published by the Free Software Foundation.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License along
  16. # with this program; if not, write to the Free Software Foundation, Inc.,
  17. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. import operator
  19. from django.db.models import Q
  20. from django.shortcuts import render
  21. from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, Target_Package, LogMessage, Variable
  22. from orm.models import Task_Dependency, Recipe_Dependency, Build_Package, Build_File, Build_Package_Dependency
  23. from django.views.decorators.cache import cache_control
  24. @cache_control(no_store=True)
  25. def build(request):
  26. template = 'build.html'
  27. build_info = Build.objects.all()
  28. logs = LogMessage.objects.all()
  29. context = {'builds': build_info, 'logs': logs ,
  30. 'hideshowcols' : [
  31. {'name': 'Output', 'order':10},
  32. {'name': 'Log', 'order':11},
  33. ]}
  34. return render(request, template, context)
  35. def _find_task_revdep(task):
  36. tp = []
  37. for p in Task_Dependency.objects.filter(depends_on=task):
  38. tp.append(p.task);
  39. return tp
  40. def _find_task_provider(task):
  41. task_revdeps = _find_task_revdep(task)
  42. for tr in task_revdeps:
  43. if tr.outcome != Task.OUTCOME_COVERED:
  44. return tr
  45. for tr in task_revdeps:
  46. trc = _find_task_provider(tr)
  47. if trc is not None:
  48. return trc
  49. return None
  50. def task(request, build_id):
  51. template = 'task.html'
  52. tasks = Task.objects.filter(build=build_id)
  53. for t in tasks:
  54. if t.outcome == Task.OUTCOME_COVERED:
  55. t.provider = _find_task_provider(t)
  56. context = {'build': Build.objects.filter(pk=build_id)[0], 'tasks': tasks}
  57. return render(request, template, context)
  58. def configuration(request, build_id):
  59. template = 'configuration.html'
  60. variables = Variable.objects.filter(build=build_id)
  61. context = {'build': Build.objects.filter(pk=build_id)[0], 'configuration' : variables}
  62. return render(request, template, context)
  63. def bpackage(request, build_id):
  64. template = 'bpackage.html'
  65. packages = Build_Package.objects.filter(build = build_id)
  66. context = {'build': Build.objects.filter(pk=build_id)[0], 'packages' : packages}
  67. return render(request, template, context)
  68. def bfile(request, build_id, package_id):
  69. template = 'bfile.html'
  70. files = Build_File.objects.filter(bpackage = package_id)
  71. context = {'build': Build.objects.filter(pk=build_id)[0], 'files' : files}
  72. return render(request, template, context)
  73. def tpackage(request, build_id, target_id):
  74. template = 'package.html'
  75. packages = Target_Package.objects.filter(target=target_id)
  76. context = {'build' : Build.objects.filter(pk=build_id)[0],'packages': packages}
  77. return render(request, template, context)
  78. def layer(request):
  79. template = 'layer.html'
  80. layer_info = Layer.objects.all()
  81. for li in layer_info:
  82. li.versions = Layer_Version.objects.filter(layer = li)
  83. for liv in li.versions:
  84. liv.count = Recipe.objects.filter(layer_version__id = liv.id).count()
  85. context = {'layers': layer_info}
  86. return render(request, template, context)
  87. def layer_versions_recipes(request, layerversion_id):
  88. template = 'recipe.html'
  89. recipes = Recipe.objects.filter(layer_version__id = layerversion_id)
  90. context = {'recipes': recipes,
  91. 'layer_version' : Layer_Version.objects.filter( id = layerversion_id )[0]
  92. }
  93. return render(request, template, context)
  94. #### API
  95. import json
  96. from django.core import serializers
  97. from django.http import HttpResponse, HttpResponseBadRequest
  98. def model_explorer(request, model_name):
  99. DESCENDING = 'desc'
  100. response_data = {}
  101. model_mapping = {
  102. 'build': Build,
  103. 'target': Target,
  104. 'target_package': Target_Package,
  105. 'task': Task,
  106. 'task_dependency': Task_Dependency,
  107. 'package': Build_Package,
  108. 'layer': Layer,
  109. 'layerversion': Layer_Version,
  110. 'recipe': Recipe,
  111. 'recipe_dependency': Recipe_Dependency,
  112. 'build_package': Build_Package,
  113. 'build_package_dependency': Build_Package_Dependency,
  114. 'build_file': Build_File,
  115. 'variable': Variable,
  116. 'logmessage': LogMessage,
  117. }
  118. if model_name not in model_mapping.keys():
  119. return HttpResponseBadRequest()
  120. model = model_mapping[model_name]
  121. try:
  122. limit = int(request.GET.get('limit', 0))
  123. except ValueError:
  124. limit = 0
  125. try:
  126. offset = int(request.GET.get('offset', 0))
  127. except ValueError:
  128. offset = 0
  129. ordering_string, invalid = _validate_input(request.GET.get('orderby', ''),
  130. model)
  131. if invalid:
  132. return HttpResponseBadRequest()
  133. filter_string, invalid = _validate_input(request.GET.get('filter', ''),
  134. model)
  135. if invalid:
  136. return HttpResponseBadRequest()
  137. search_term = request.GET.get('search', '')
  138. if filter_string:
  139. filter_terms = _get_filtering_terms(filter_string)
  140. try:
  141. queryset = model.objects.filter(**filter_terms)
  142. except ValueError:
  143. queryset = []
  144. else:
  145. queryset = model.objects.all()
  146. if search_term:
  147. queryset = _get_search_results(search_term, queryset, model)
  148. if ordering_string and queryset:
  149. column, order = ordering_string.split(':')
  150. if order.lower() == DESCENDING:
  151. queryset = queryset.order_by('-' + column)
  152. else:
  153. queryset = queryset.order_by(column)
  154. if offset and limit:
  155. queryset = queryset[offset:(offset+limit)]
  156. elif offset:
  157. queryset = queryset[offset:]
  158. elif limit:
  159. queryset = queryset[:limit]
  160. if queryset:
  161. response_data['count'] = queryset.count()
  162. else:
  163. response_data['count'] = 0
  164. response_data['list'] = serializers.serialize('json', queryset)
  165. return HttpResponse(json.dumps(response_data),
  166. content_type='application/json')
  167. def _get_filtering_terms(filter_string):
  168. search_terms = filter_string.split(":")
  169. keys = search_terms[0].split(',')
  170. values = search_terms[1].split(',')
  171. return dict(zip(keys, values))
  172. def _validate_input(input, model):
  173. invalid = 0
  174. if input:
  175. input_list = input.split(":")
  176. # Check we have only one colon
  177. if len(input_list) != 2:
  178. invalid = 1
  179. return None, invalid
  180. # Check we have an equal number of terms both sides of the colon
  181. if len(input_list[0].split(',')) != len(input_list[1].split(',')):
  182. invalid = 1
  183. return None, invalid
  184. # Check we are looking for a valid field
  185. valid_fields = model._meta.get_all_field_names()
  186. for field in input_list[0].split(','):
  187. if field not in valid_fields:
  188. invalid = 1
  189. return None, invalid
  190. return input, invalid
  191. def _get_search_results(search_term, queryset, model):
  192. search_objects = []
  193. for st in search_term.split(" "):
  194. q_map = map(lambda x: Q(**{x+'__icontains': st}),
  195. model.search_allowed_fields)
  196. search_objects.append(reduce(operator.or_, q_map))
  197. search_object = reduce(operator.and_, search_objects)
  198. queryset = queryset.filter(search_object)
  199. return queryset