summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitbake/lib/toaster/orm/models.py68
-rw-r--r--bitbake/lib/toaster/toastergui/tables.py8
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py38
3 files changed, 73 insertions, 41 deletions
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 7e0cf9676a..b7975ef865 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -29,6 +29,9 @@ from django.core import validators
29from django.conf import settings 29from django.conf import settings
30import django.db.models.signals 30import django.db.models.signals
31 31
32import os.path
33import re
34
32import logging 35import logging
33logger = logging.getLogger("toaster") 36logger = logging.getLogger("toaster")
34 37
@@ -234,6 +237,14 @@ class Project(models.Model):
234 except (Build.DoesNotExist,IndexError): 237 except (Build.DoesNotExist,IndexError):
235 return( "not_found" ) 238 return( "not_found" )
236 239
240 def get_last_build_extensions(self):
241 """
242 Get list of file name extensions for images produced by the most
243 recent build
244 """
245 last_build = Build.objects.get(pk = self.get_last_build_id())
246 return last_build.get_image_file_extensions()
247
237 def get_last_imgfiles(self): 248 def get_last_imgfiles(self):
238 build_id = self.get_last_build_id 249 build_id = self.get_last_build_id
239 if (-1 == build_id): 250 if (-1 == build_id):
@@ -376,6 +387,57 @@ class Build(models.Model):
376 eta += ((eta - self.started_on)*(100-completeper))/completeper 387 eta += ((eta - self.started_on)*(100-completeper))/completeper
377 return eta 388 return eta
378 389
390 def get_image_file_extensions(self):
391 """
392 Get list of file name extensions for images produced by this build
393 """
394 targets = Target.objects.filter(build_id = self.id)
395 extensions = []
396
397 # pattern to match against file path for building extension string
398 pattern = re.compile('\.([^\.]+?)$')
399
400 for target in targets:
401 if (not target.is_image):
402 continue
403
404 target_image_files = Target_Image_File.objects.filter(target_id = target.id)
405
406 for target_image_file in target_image_files:
407 file_name = os.path.basename(target_image_file.file_name)
408 suffix = ''
409
410 continue_matching = True
411
412 # incrementally extract the suffix from the file path,
413 # checking it against the list of valid suffixes at each
414 # step; if the path is stripped of all potential suffix
415 # parts without matching a valid suffix, this returns all
416 # characters after the first '.' in the file name
417 while continue_matching:
418 matches = pattern.search(file_name)
419
420 if None == matches:
421 continue_matching = False
422 suffix = re.sub('^\.', '', suffix)
423 continue
424 else:
425 suffix = matches.group(1) + suffix
426
427 if suffix in Target_Image_File.SUFFIXES:
428 continue_matching = False
429 continue
430 else:
431 # reduce the file name and try to find the next
432 # segment from the path which might be part
433 # of the suffix
434 file_name = re.sub('.' + matches.group(1), '', file_name)
435 suffix = '.' + suffix
436
437 if not suffix in extensions:
438 extensions.append(suffix)
439
440 return ', '.join(extensions)
379 441
380 def get_sorted_target_list(self): 442 def get_sorted_target_list(self):
381 tgts = Target.objects.filter(build_id = self.id).order_by( 'target' ); 443 tgts = Target.objects.filter(build_id = self.id).order_by( 'target' );
@@ -418,7 +480,7 @@ class Build(models.Model):
418 return self.get_outcome_text() 480 return self.get_outcome_text()
419 481
420 def __str__(self): 482 def __str__(self):
421 return "%s %s %s" % (self.id, self.project, ",".join([t.target for t in self.target_set.all()])) 483 return "%d %s %s" % (self.id, self.project, ",".join([t.target for t in self.target_set.all()]))
422 484
423 485
424# an Artifact is anything that results from a Build, and may be of interest to the user, and is not stored elsewhere 486# an Artifact is anything that results from a Build, and may be of interest to the user, and is not stored elsewhere
@@ -609,7 +671,7 @@ class Task(models.Model):
609 sstate_text = property(get_sstate_text) 671 sstate_text = property(get_sstate_text)
610 672
611 def __unicode__(self): 673 def __unicode__(self):
612 return "%s(%s) %s:%s" % (self.pk, self.build.pk, self.recipe.name, self.task_name) 674 return "%d(%d) %s:%s" % (self.pk, self.build.pk, self.recipe.name, self.task_name)
613 675
614 class Meta: 676 class Meta:
615 ordering = ('order', 'recipe' ,) 677 ordering = ('order', 'recipe' ,)
@@ -1265,7 +1327,7 @@ class Layer_Version(models.Model):
1265 return sorted(result, key=lambda x: x.layer.name) 1327 return sorted(result, key=lambda x: x.layer.name)
1266 1328
1267 def __unicode__(self): 1329 def __unicode__(self):
1268 return "%s %s (VCS %s, Project %s)" % (self.pk, str(self.layer), self.get_vcs_reference(), self.build.project if self.build is not None else "No project") 1330 return "%d %s (VCS %s, Project %s)" % (self.pk, str(self.layer), self.get_vcs_reference(), self.build.project if self.build is not None else "No project")
1269 1331
1270 class Meta: 1332 class Meta:
1271 unique_together = ("layer_source", "up_id") 1333 unique_together = ("layer_source", "up_id")
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py
index e5cab48c48..cc9b5aef40 100644
--- a/bitbake/lib/toaster/toastergui/tables.py
+++ b/bitbake/lib/toaster/toastergui/tables.py
@@ -661,7 +661,7 @@ class ProjectsTable(ToasterTable):
661 661
662 self.queryset = queryset 662 self.queryset = queryset
663 663
664 # columns: last activity on (updated) - DEFAULT, project (name), release, machine, number of builds, last build outcome, recipe (name), errors, warnings, image files 664 # columns: last activity on (updated) - DEFAULT, project (name), release, machine, number of builds, last build outcome, recipe (name), errors, warnings, image files
665 def setup_columns(self, *args, **kwargs): 665 def setup_columns(self, *args, **kwargs):
666 name_template = ''' 666 name_template = '''
667 {% load project_url_tag %} 667 {% load project_url_tag %}
@@ -767,10 +767,9 @@ class ProjectsTable(ToasterTable):
767 ''' 767 '''
768 768
769 image_files_template = ''' 769 image_files_template = '''
770 {% load projecttags %}
771 {% if data.get_number_of_builds > 0 and data.get_last_outcome == extra.Build.SUCCEEDED %} 770 {% if data.get_number_of_builds > 0 and data.get_last_outcome == extra.Build.SUCCEEDED %}
772 <a href="{% url "builddashboard" data.get_last_build_id %}#images"> 771 <a href="{% url "builddashboard" data.get_last_build_id %}#images">
773 {{fstypes | get_dict_value:data.id}} 772 {{data.get_last_build_extensions}}
774 </a> 773 </a>
775 {% endif %} 774 {% endif %}
776 ''' 775 '''
@@ -848,7 +847,8 @@ class ProjectsTable(ToasterTable):
848 static_data_template=warnings_template) 847 static_data_template=warnings_template)
849 848
850 self.add_column(title='Image files', 849 self.add_column(title='Image files',
851 help_text='', 850 help_text='The root file system types produced by \
851 the last project build',
852 hideable=True, 852 hideable=True,
853 orderable=False, 853 orderable=False,
854 static_data_name='image_files', 854 static_data_name='image_files',
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 4cd7afde7c..8148623a8b 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -2008,23 +2008,10 @@ if True:
2008 context_date,today_begin,yesterday_begin = _add_daterange_context(queryset_all, request, {'started_on','completed_on'}) 2008 context_date,today_begin,yesterday_begin = _add_daterange_context(queryset_all, request, {'started_on','completed_on'})
2009 2009
2010 # set up list of fstypes for each build 2010 # set up list of fstypes for each build
2011 fstypes_map = {}; 2011 fstypes_map = {}
2012
2012 for build in build_info: 2013 for build in build_info:
2013 targets = Target.objects.filter( build_id = build.id ) 2014 fstypes_map[build.id] = build.get_image_file_extensions()
2014 comma = "";
2015 extensions = "";
2016 for t in targets:
2017 if ( not t.is_image ):
2018 continue
2019 tif = Target_Image_File.objects.filter( target_id = t.id )
2020 for i in tif:
2021 s=re.sub('.*tar.bz2', 'tar.bz2', i.file_name)
2022 if s == i.file_name:
2023 s=re.sub('.*\.', '', i.file_name)
2024 if None == re.search(s,extensions):
2025 extensions += comma + s
2026 comma = ", "
2027 fstypes_map[build.id]=extensions
2028 2015
2029 # send the data to the template 2016 # send the data to the template
2030 context = { 2017 context = {
@@ -3047,24 +3034,7 @@ if True:
3047 # translate the project's build target strings 3034 # translate the project's build target strings
3048 fstypes_map = {}; 3035 fstypes_map = {};
3049 for project in project_info: 3036 for project in project_info:
3050 try: 3037 fstypes_map[project.id] = project.get_last_build_extensions()
3051 targets = Target.objects.filter( build_id = project.get_last_build_id() )
3052 comma = "";
3053 extensions = "";
3054 for t in targets:
3055 if ( not t.is_image ):
3056 continue
3057 tif = Target_Image_File.objects.filter( target_id = t.id )
3058 for i in tif:
3059 s=re.sub('.*tar.bz2', 'tar.bz2', i.file_name)
3060 if s == i.file_name:
3061 s=re.sub('.*\.', '', i.file_name)
3062 if None == re.search(s,extensions):
3063 extensions += comma + s
3064 comma = ", "
3065 fstypes_map[project.id]=extensions
3066 except (Target.DoesNotExist,IndexError):
3067 fstypes_map[project.id]=project.get_last_imgfiles
3068 3038
3069 context = { 3039 context = {
3070 'mru' : build_mru, 3040 'mru' : build_mru,