1# 2# BitBake Toaster Implementation 3# 4# Copyright (C) 2015 Intel Corporation 5# 6# SPDX-License-Identifier: GPL-2.0-only 7# 8 9import subprocess 10 11from toastergui.widgets import ToasterTypeAhead 12from orm.models import Project 13from django.urls import reverse 14from django.core.cache import cache 15 16 17class LayersTypeAhead(ToasterTypeAhead): 18 """ Typeahead for layers available and not added in the current project's 19 configuration """ 20 21 def apply_search(self, search_term, prj, request): 22 layers = prj.get_all_compatible_layer_versions() 23 layers = layers.order_by('layer__name') 24 25 # Unlike the other typeaheads we also don't want to show suggestions 26 # for layers already in the project unless required such as when adding 27 # layerdeps to a new layer. 28 if "include_added" in request.GET and \ 29 request.GET['include_added'] != "true": 30 layers = layers.exclude( 31 pk__in=prj.get_project_layer_versions(pk=True)) 32 33 primary_results = layers.filter(layer__name__istartswith=search_term) 34 secondary_results = layers.filter( 35 layer__name__icontains=search_term).exclude( 36 pk__in=primary_results) 37 38 results = [] 39 40 for layer_version in list(primary_results) + list(secondary_results): 41 vcs_reference = layer_version.get_vcs_reference() 42 43 detail = "[ %s | %s ]" % (layer_version.layer.vcs_url, 44 vcs_reference) 45 needed_fields = { 46 'id': layer_version.pk, 47 'name': layer_version.layer.name, 48 'layerdetailurl': layer_version.get_detailspage_url(prj.pk), 49 'xhrLayerUrl': reverse('xhr_layer', 50 args=(prj.pk, layer_version.pk)), 51 'vcs_url': layer_version.layer.vcs_url, 52 'vcs_reference': vcs_reference, 53 'detail': detail, 54 'local_source_dir': layer_version.layer.local_source_dir, 55 } 56 57 results.append(needed_fields) 58 59 return results 60 61 62class MachinesTypeAhead(ToasterTypeAhead): 63 """ Typeahead for all the machines available in the current project's 64 configuration """ 65 66 def apply_search(self, search_term, prj, request): 67 machines = prj.get_available_machines() 68 machines = machines.order_by("name") 69 70 primary_results = machines.filter(name__istartswith=search_term) 71 secondary_results = machines.filter( 72 name__icontains=search_term).exclude(pk__in=primary_results) 73 tertiary_results = machines.filter( 74 layer_version__layer__name__icontains=search_term).exclude( 75 pk__in=primary_results).exclude(pk__in=secondary_results) 76 77 results = [] 78 79 for machine in list(primary_results) + list(secondary_results) + \ 80 list(tertiary_results): 81 82 detail = "[ %s ]" % (machine.layer_version.layer.name) 83 needed_fields = { 84 'id': machine.pk, 85 'name': machine.name, 86 'detail': detail, 87 } 88 89 results.append(needed_fields) 90 return results 91 92 93class DistrosTypeAhead(ToasterTypeAhead): 94 """ Typeahead for all the distros available in the current project's 95 configuration """ 96 def __init__(self): 97 super(DistrosTypeAhead, self).__init__() 98 99 def apply_search(self, search_term, prj, request): 100 distros = prj.get_available_distros() 101 distros = distros.order_by("name") 102 103 primary_results = distros.filter(name__istartswith=search_term) 104 secondary_results = distros.filter(name__icontains=search_term).exclude(pk__in=primary_results) 105 tertiary_results = distros.filter(layer_version__layer__name__icontains=search_term).exclude(pk__in=primary_results).exclude(pk__in=secondary_results) 106 107 results = [] 108 109 for distro in list(primary_results) + list(secondary_results) + list(tertiary_results): 110 111 detail = "[ %s ]" % (distro.layer_version.layer.name) 112 needed_fields = { 113 'id' : distro.pk, 114 'name' : distro.name, 115 'detail' : detail, 116 } 117 118 results.append(needed_fields) 119 120 return results 121 122 123class RecipesTypeAhead(ToasterTypeAhead): 124 """ Typeahead for all the recipes available in the current project's 125 configuration """ 126 def apply_search(self, search_term, prj, request): 127 recipes = prj.get_available_recipes() 128 recipes = recipes.order_by("name") 129 130 primary_results = recipes.filter(name__istartswith=search_term) 131 secondary_results = recipes.filter( 132 name__icontains=search_term).exclude(pk__in=primary_results) 133 tertiary_results = recipes.filter( 134 layer_version__layer__name__icontains=search_term).exclude( 135 pk__in=primary_results).exclude(pk__in=secondary_results) 136 137 results = [] 138 139 for recipe in list(primary_results) + list(secondary_results) + \ 140 list(tertiary_results): 141 142 detail = "[ %s ]" % (recipe.layer_version.layer.name) 143 needed_fields = { 144 'id': recipe.pk, 145 'name': recipe.name, 146 'detail': detail, 147 } 148 149 results.append(needed_fields) 150 151 return results 152 153 154class ProjectsTypeAhead(ToasterTypeAhead): 155 """ Typeahead for all the projects, except for command line builds """ 156 def apply_search(self, search_term, prj, request): 157 projects = Project.objects.exclude(is_default=True).order_by("name") 158 159 primary_results = projects.filter(name__istartswith=search_term) 160 secondary_results = projects.filter( 161 name__icontains=search_term).exclude(pk__in=primary_results) 162 163 results = [] 164 165 for project in list(primary_results) + list(secondary_results): 166 needed_fields = { 167 'id': project.pk, 168 'name': project.name, 169 'detail': "", 170 'projectPageUrl': reverse('project', args=(project.pk,)) 171 } 172 173 results.append(needed_fields) 174 175 return results 176 177 178class GitRevisionTypeAhead(ToasterTypeAhead): 179 def apply_search(self, search_term, prj, request): 180 results = [] 181 git_url = request.GET.get('git_url') 182 ls_remote = cache.get(git_url) 183 184 if ls_remote is None: 185 ls_remote = subprocess.check_output(['git', 'ls-remote', git_url], 186 universal_newlines=True) 187 ls_remote = ls_remote.splitlines() 188 # Avoid fetching the list of git refs on each new input 189 cache.set(git_url, ls_remote, 120) 190 191 for rev in ls_remote: 192 git_rev = str(rev).split("/")[-1:][0] 193 # "HEAD" has a special meaning in Toaster... YOCTO #9924 194 if "HEAD" in git_rev: 195 continue 196 197 if git_rev.startswith(search_term): 198 results.append({'name': git_rev, 199 'detail': '[ %s ]' % str(rev)}) 200 201 return results 202