diff options
author | Elliot Smith <elliot.smith@intel.com> | 2016-01-15 13:01:04 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-01-15 16:30:01 +0000 |
commit | 88a262cbd231b452f0b50cc37bec7189e5796710 (patch) | |
tree | 768eed3f481a70a7cd2fd571e5e79d0832c5be78 | |
parent | 059a274aa96ced872156806936f887969980dda6 (diff) | |
download | poky-88a262cbd231b452f0b50cc37bec7189e5796710.tar.gz |
bitbake: toastergui: remove unused views and template code
The code in views.py for setting up the template context for
old non-ToasterTable views is no longer necessary, as this
is now implemented in tables.py.
The template files for these views have also been removed.
[YOCTO #8738]
(Bitbake rev: 2b5a13afb068c85466436914d8d4ac3b31bc5c02)
Signed-off-by: Elliot Smith <elliot.smith@intel.com>
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/builds.html | 125 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/projects.html | 92 | ||||
-rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 430 |
3 files changed, 0 insertions, 647 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/builds.html b/bitbake/lib/toaster/toastergui/templates/builds.html deleted file mode 100644 index c3cc266daf..0000000000 --- a/bitbake/lib/toaster/toastergui/templates/builds.html +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
1 | {% extends "base.html" %} | ||
2 | |||
3 | {% load static %} | ||
4 | {% load projecttags %} | ||
5 | {% load project_url_tag %} | ||
6 | {% load humanize %} | ||
7 | |||
8 | {% block title %} All builds - Toaster {% endblock %} | ||
9 | {% block extraheadcontent %} | ||
10 | <link rel="stylesheet" href="/static/css/jquery-ui.min.css" type='text/css'> | ||
11 | <link rel="stylesheet" href="/static/css/jquery-ui.structure.min.css" type='text/css'> | ||
12 | <link rel="stylesheet" href="/static/css/jquery-ui.theme.min.css" type='text/css'> | ||
13 | <script src="/static/js/jquery-ui.min.js"></script> | ||
14 | <script src="/static/js/filtersnippet.js"></script> | ||
15 | {% endblock %} | ||
16 | |||
17 | {% block pagecontent %} | ||
18 | |||
19 | {% if last_date_from and last_date_to %} | ||
20 | <script> | ||
21 | // initialize the date range controls | ||
22 | $(document).ready(function () { | ||
23 | date_init('started_on','{{last_date_from}}','{{last_date_to}}','{{dateMin_started_on}}','{{dateMax_started_on}}','{{daterange_selected}}'); | ||
24 | date_init('completed_on','{{last_date_from}}','{{last_date_to}}','{{dateMin_completed_on}}','{{dateMax_completed_on}}','{{daterange_selected}}'); | ||
25 | }); | ||
26 | </script> | ||
27 | {%endif%} {# last_date_from and last_date_to #} | ||
28 | |||
29 | <div class="row-fluid"> | ||
30 | |||
31 | {% include "mrb_section.html" %} | ||
32 | |||
33 | <div class="page-header top-air"> | ||
34 | <h1> | ||
35 | {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} | ||
36 | {{objects.paginator.count}} build{{objects.paginator.count|pluralize}} found | ||
37 | {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} | ||
38 | No builds found | ||
39 | {%else%} | ||
40 | All builds | ||
41 | {%endif%} | ||
42 | </h1> | ||
43 | </div> | ||
44 | |||
45 | {% if objects.paginator.count == 0 %} | ||
46 | <div class="row-fluid"> | ||
47 | <div class="alert"> | ||
48 | <form class="no-results input-append" id="searchform"> | ||
49 | <input id="search" name="search" class="input-xxlarge" type="text" value=" | ||
50 | {% if request.GET.search %} | ||
51 | {{request.GET.search}} | ||
52 | {% endif %}"/> | ||
53 | {% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} | ||
54 | <button class="btn" type="submit" value="Search">Search</button> | ||
55 | <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all builds</button> | ||
56 | </form> | ||
57 | </div> | ||
58 | </div> | ||
59 | {% else %} | ||
60 | {% include "basetable_top.html" %} | ||
61 | <!-- Table data rows; the order needs to match the order of "tablecols" definitions; and the <td class value needs to match the tablecols clclass value for show/hide buttons to work --> | ||
62 | {% for build in objects %} | ||
63 | <tr class="data" data-table-build-result="{{ build.id }}"> | ||
64 | <td class="outcome"> | ||
65 | <a href="{% url "builddashboard" build.id %}">{%if build.outcome == build.SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif build.outcome == build.FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a> | ||
66 | {% if build.cooker_log_path %} | ||
67 | | ||
68 | <a href="{% url 'build_artifact' build.id "cookerlog" build.id %}"> | ||
69 | <i class="icon-download-alt" title="Download build log"></i> | ||
70 | </a> | ||
71 | {% endif %} | ||
72 | </td> | ||
73 | <td class="target"> | ||
74 | {% for t in build.target_set.all %} | ||
75 | <a href="{% url "builddashboard" build.id %}"> | ||
76 | {% if t.task %} | ||
77 | {{t.target}}:{{t.task}} | ||
78 | {% else %} | ||
79 | {{t.target}} | ||
80 | {% endif %} | ||
81 | </a> <br /> | ||
82 | {% endfor %} | ||
83 | </td> | ||
84 | <td class="machine"><a href="{% url "builddashboard" build.id %}">{{build.machine}}</a></td> | ||
85 | <td class="started_on"><a href="{% url "builddashboard" build.id %}">{{build.started_on|date:"d/m/y H:i"}}</a></td> | ||
86 | <td class="completed_on"><a href="{% url "builddashboard" build.id %}">{{build.completed_on|date:"d/m/y H:i"}}</a></td> | ||
87 | <td class="failed_tasks error"> | ||
88 | {% query build.task_build outcome=4 order__gt=0 as exectask%} | ||
89 | {% if exectask.count == 1 %} | ||
90 | <a href="{% url "task" build.id exectask.0.id %}">{{exectask.0.recipe.name}}.{{exectask.0.task_name}}</a> | ||
91 | <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}"> | ||
92 | <i class="icon-download-alt" title="" data-original-title="Download task log file"></i> | ||
93 | </a> | ||
94 | {% elif exectask.count > 1%} | ||
95 | <a href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}} task{{exectask.count|pluralize}}</a> | ||
96 | {%endif%} | ||
97 | </td> | ||
98 | <td class="errors.count errors_no"> | ||
99 | {% if build.errors.count %} | ||
100 | <a class="errors.count error" href="{% url "builddashboard" build.id %}#errors">{{build.errors.count}} error{{build.errors.count|pluralize}}</a> | ||
101 | {%endif%} | ||
102 | </td> | ||
103 | <td class="warnings.count warnings_no">{% if build.warnings.count %}<a class="warnings.count warning" href="{% url "builddashboard" build.id %}#warnings">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>{%endif%}</td> | ||
104 | <td class="time"><a href="{% url "buildtime" build.id %}">{{build.timespent_seconds|sectohms}}</a></td> | ||
105 | <td class="output"> | ||
106 | {% if build.outcome == build.SUCCEEDED %} | ||
107 | <a href="{%url "builddashboard" build.id%}#images">{{fstypes|get_dict_value:build.id}}</a> | ||
108 | {% endif %} | ||
109 | </td> | ||
110 | <td class="project-name"> | ||
111 | <a href="{% project_url build.project %}">{{build.project.name}}</a> | ||
112 | {% if build.project.is_default %} | ||
113 | <i class="icon-question-sign get-help hover-help" title="" data-original-title="This project shows information about the builds you start from the command line while Toaster is running" style="visibility: hidden;"></i> | ||
114 | {% endif %} | ||
115 | </td> | ||
116 | </tr> | ||
117 | |||
118 | {% endfor %} | ||
119 | |||
120 | |||
121 | {% include "basetable_bottom.html" %} | ||
122 | {% endif %} {# objects.paginator.count #} | ||
123 | </div><!-- end row-fluid--> | ||
124 | |||
125 | {% endblock %} | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/projects.html b/bitbake/lib/toaster/toastergui/templates/projects.html deleted file mode 100644 index 678a7963b7..0000000000 --- a/bitbake/lib/toaster/toastergui/templates/projects.html +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | {% extends "base.html" %} | ||
2 | |||
3 | {% load static %} | ||
4 | {% load projecttags %} | ||
5 | {% load project_url_tag %} | ||
6 | {% load humanize %} | ||
7 | |||
8 | {% block title %} All projects - Toaster {% endblock %} | ||
9 | |||
10 | {% block pagecontent %} | ||
11 | |||
12 | |||
13 | <div class="page-header top-air"> | ||
14 | <h1> | ||
15 | {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} | ||
16 | {{objects.paginator.count}} project{{objects.paginator.count|pluralize}} found | ||
17 | {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} | ||
18 | No projects found | ||
19 | {%else%} | ||
20 | All projects | ||
21 | {%endif%} | ||
22 | </h1> | ||
23 | </div> | ||
24 | |||
25 | {% if objects.paginator.count == 0 %} | ||
26 | <div class="row-fluid"> | ||
27 | <div class="alert"> | ||
28 | <form class="no-results input-append" id="searchform"> | ||
29 | <input id="search" name="search" class="input-xxlarge" type="text" value=" | ||
30 | {% if request.GET.search %} | ||
31 | {{request.GET.search}} | ||
32 | {% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} | ||
33 | <button class="btn" type="submit" value="Search">Search</button> | ||
34 | <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all projects</button> | ||
35 | </form> | ||
36 | </div> | ||
37 | </div> | ||
38 | |||
39 | {% else %} {# We have builds to display #} | ||
40 | {% include "basetable_top.html" %} | ||
41 | {% for o in objects %} | ||
42 | <tr class="data" data-project="{{ o.id }}"> | ||
43 | <td data-project-field="name"> | ||
44 | <a href="{% project_url o %}">{{o.name}}</a> | ||
45 | </td> | ||
46 | <td class="updated"><a href="{% project_url o %}">{{o.updated|date:"d/m/y H:i"}}</a></td> | ||
47 | <td data-project-field="release"> | ||
48 | {% if o.release %} | ||
49 | <a href="{% url 'project' o.id %}#project-details">{{o.release.name}}</a> | ||
50 | {% elif o.is_default %} | ||
51 | <span class="muted">Not applicable</span> | ||
52 | <i class="icon-question-sign get-help hover-help" title="" data-original-title="This project does not have a release set. It simply collects information about the builds you start from the command line while Toaster is running" style="visibility: hidden;"></i> | ||
53 | {% else %} | ||
54 | No release available | ||
55 | {% endif %} | ||
56 | </td> | ||
57 | <td data-project-field="machine"> | ||
58 | {% if o.is_default %} | ||
59 | <span class="muted">Not applicable</span> | ||
60 | <i class="icon-question-sign get-help hover-help" title="" data-original-title="This project does not have a machine set. It simply collects information about the builds you start from the command line while Toaster is running" style="visibility: hidden;"></i> | ||
61 | {% else %} | ||
62 | <a href="{% url 'project' o.id %}#machine-distro">{{o.get_current_machine_name}}</a> | ||
63 | {% endif %} | ||
64 | </td> | ||
65 | {% if o.get_number_of_builds == 0 %} | ||
66 | <td class="muted">{{o.get_number_of_builds}}</td> | ||
67 | <td class="loutcome"></td> | ||
68 | <td class="ltarget"></td> | ||
69 | <td class="lerrors"></td> | ||
70 | <td class="lwarnings"></td> | ||
71 | <td class="limagefiles"></td> | ||
72 | {% else %} | ||
73 | <td><a href="{% url 'projectbuilds' o.id %}">{{o.get_number_of_builds}}</a></td> | ||
74 | <td class="loutcome"><a href="{% url "builddashboard" o.get_last_build_id %}">{%if o.get_last_outcome == build_SUCCEEDED%}<i class="icon-ok-sign success"></i>{%elif o.get_last_outcome == build_FAILED%}<i class="icon-minus-sign error"></i>{%else%}{%endif%}</a></td> | ||
75 | <td class="ltarget"><a href="{% url "builddashboard" o.get_last_build_id %}">{{o.get_last_target}} </a></td> | ||
76 | <td class="lerrors">{% if o.get_last_errors %}<a class="errors.count error" href="{% url "builddashboard" o.get_last_build_id %}#errors">{{o.get_last_errors}} error{{o.get_last_errors|pluralize}}</a>{%endif%}</td> | ||
77 | <td class="lwarnings">{% if o.get_last_warnings %}<a class="warnings.count warning" href="{% url "builddashboard" o.get_last_build_id %}#warnings">{{o.get_last_warnings}} warning{{o.get_last_warnings|pluralize}}</a>{%endif%}</td> | ||
78 | <td class="limagefiles"> | ||
79 | {% if o.get_last_outcome == build_SUCCEEDED %} | ||
80 | <a href="{%url "builddashboard" o.get_last_build_id %}#images">{{fstypes|get_dict_value:o.id}}</a> | ||
81 | {% endif %} | ||
82 | </td> | ||
83 | |||
84 | {% endif %} | ||
85 | </tr> | ||
86 | {% endfor %} | ||
87 | {% include "basetable_bottom.html" %} | ||
88 | {% endif %} {# empty #} | ||
89 | |||
90 | {% endblock %} | ||
91 | |||
92 | |||
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 3e8a66bfb1..4f7b50f9dc 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
@@ -92,50 +92,6 @@ def landing(request): | |||
92 | 92 | ||
93 | return render(request, 'landing.html', context) | 93 | return render(request, 'landing.html', context) |
94 | 94 | ||
95 | """ | ||
96 | # returns a list for most recent builds; | ||
97 | def _get_latest_builds(prj=None): | ||
98 | queryset = Build.objects.all() | ||
99 | |||
100 | if prj is not None: | ||
101 | queryset = queryset.filter(project = prj) | ||
102 | |||
103 | return list(itertools.chain( | ||
104 | queryset.filter(outcome=Build.IN_PROGRESS).order_by("-started_on"), | ||
105 | queryset.filter(outcome__lt=Build.IN_PROGRESS).order_by("-started_on")[:3] )) | ||
106 | """ | ||
107 | |||
108 | """ | ||
109 | # a JSON-able dict of recent builds; for use in the Project page, xhr_ updates, and other places, as needed | ||
110 | def _project_recent_build_list(prj): | ||
111 | data = [] | ||
112 | # take the most recent 3 completed builds, plus any builds in progress | ||
113 | for x in _get_latest_builds(prj): | ||
114 | d = { | ||
115 | "id": x.pk, | ||
116 | "targets" : map(lambda y: {"target": y.target, "task": y.task }, x.target_set.all()), # TODO: create the task entry in the Target table | ||
117 | "status": x.get_current_status(), | ||
118 | "errors": map(lambda y: {"type": y.lineno, "msg": y.message, "tb": y.pathname}, (x.logmessage_set.filter(level__gte=LogMessage.WARNING)|x.logmessage_set.filter(level=LogMessage.EXCEPTION))), | ||
119 | "updated": x.completed_on.strftime('%s')+"000", | ||
120 | "command_time": (x.completed_on - x.started_on).total_seconds(), | ||
121 | "br_page_url": reverse('builddashboard', args=(x.pk,) ), | ||
122 | "build" : map( lambda y: {"id": y.pk, | ||
123 | "status": y.get_outcome_display(), | ||
124 | "completed_on" : y.completed_on.strftime('%s')+"000", | ||
125 | "build_time" : (y.completed_on - y.started_on).total_seconds(), | ||
126 | "build_page_url" : reverse('builddashboard', args=(y.pk,)), | ||
127 | 'build_time_page_url': reverse('buildtime', args=(y.pk,)), | ||
128 | "errors": y.errors.count(), | ||
129 | "warnings": y.warnings.count(), | ||
130 | "completeper": y.completeper() if y.outcome == Build.IN_PROGRESS else "0", | ||
131 | "eta": y.eta().strftime('%s')+"000" if y.outcome == Build.IN_PROGRESS else "0", | ||
132 | }, [x]), | ||
133 | } | ||
134 | data.append(d) | ||
135 | |||
136 | return data | ||
137 | """ | ||
138 | |||
139 | def objtojson(obj): | 95 | def objtojson(obj): |
140 | from django.db.models.query import QuerySet | 96 | from django.db.models.query import QuerySet |
141 | from django.db.models import Model | 97 | from django.db.models import Model |
@@ -1919,215 +1875,6 @@ if True: | |||
1919 | ''' The exception raised on invalid POST requests ''' | 1875 | ''' The exception raised on invalid POST requests ''' |
1920 | pass | 1876 | pass |
1921 | 1877 | ||
1922 | """ | ||
1923 | # helper function, to be used on "all builds" and "project builds" pages | ||
1924 | def _build_list_helper(request, queryset_all, redirect_page, pid=None): | ||
1925 | default_orderby = 'completed_on:-' | ||
1926 | (pagesize, orderby) = _get_parameters_values(request, 10, default_orderby) | ||
1927 | mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby } | ||
1928 | retval = _verify_parameters( request.GET, mandatory_parameters ) | ||
1929 | if retval: | ||
1930 | params = {} | ||
1931 | if pid: | ||
1932 | params = {'pid': pid} | ||
1933 | raise RedirectException(redirect_page, | ||
1934 | request.GET, | ||
1935 | mandatory_parameters, | ||
1936 | **params) | ||
1937 | |||
1938 | # boilerplate code that takes a request for an object type and returns a queryset | ||
1939 | # for that object type. copypasta for all needed table searches | ||
1940 | (filter_string, search_term, ordering_string) = _search_tuple(request, Build) | ||
1941 | |||
1942 | # post-process any date range filters | ||
1943 | filter_string, daterange_selected = _modify_date_range_filter(filter_string) | ||
1944 | |||
1945 | # don't show "in progress" builds in "all builds" or "project builds" | ||
1946 | queryset_all = queryset_all.exclude(outcome = Build.IN_PROGRESS) | ||
1947 | |||
1948 | # append project info | ||
1949 | queryset_all = queryset_all.select_related("project") | ||
1950 | |||
1951 | # annotate with number of ERROR and EXCEPTION log messages | ||
1952 | queryset_all = queryset_all.annotate( | ||
1953 | errors_no = Count( | ||
1954 | 'logmessage', | ||
1955 | only=Q(logmessage__level=LogMessage.ERROR) | | ||
1956 | Q(logmessage__level=LogMessage.EXCEPTION) | ||
1957 | ) | ||
1958 | ) | ||
1959 | |||
1960 | # annotate with number of warnings | ||
1961 | q_warnings = Q(logmessage__level=LogMessage.WARNING) | ||
1962 | queryset_all = queryset_all.annotate( | ||
1963 | warnings_no = Count('logmessage', only=q_warnings) | ||
1964 | ) | ||
1965 | |||
1966 | queryset_with_search = _get_queryset(Build, queryset_all, | ||
1967 | None, search_term, | ||
1968 | ordering_string, '-completed_on') | ||
1969 | |||
1970 | queryset = _get_queryset(Build, queryset_all, | ||
1971 | filter_string, search_term, | ||
1972 | ordering_string, '-completed_on') | ||
1973 | |||
1974 | # retrieve the objects that will be displayed in the table; builds a paginator and gets a page range to display | ||
1975 | build_info = _build_page_range(Paginator(queryset, pagesize), request.GET.get('page', 1)) | ||
1976 | |||
1977 | # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds) | ||
1978 | build_mru = _get_latest_builds()[:3] | ||
1979 | |||
1980 | # calculate the exact begining of local today and yesterday, append context | ||
1981 | context_date,today_begin,yesterday_begin = _add_daterange_context(queryset_all, request, {'started_on','completed_on'}) | ||
1982 | |||
1983 | # set up list of fstypes for each build | ||
1984 | fstypes_map = {} | ||
1985 | |||
1986 | for build in build_info: | ||
1987 | fstypes_map[build.id] = build.get_image_file_extensions() | ||
1988 | |||
1989 | # send the data to the template | ||
1990 | context = { | ||
1991 | # specific info for | ||
1992 | 'mru' : build_mru, | ||
1993 | # TODO: common objects for all table views, adapt as needed | ||
1994 | 'objects' : build_info, | ||
1995 | 'objectname' : "builds", | ||
1996 | 'default_orderby' : default_orderby, | ||
1997 | 'fstypes' : fstypes_map, | ||
1998 | 'search_term' : search_term, | ||
1999 | 'total_count' : queryset_with_search.count(), | ||
2000 | 'daterange_selected' : daterange_selected, | ||
2001 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns | ||
2002 | 'tablecols' : [ | ||
2003 | {'name': 'Outcome', # column with a single filter | ||
2004 | 'qhelp' : "The outcome tells you if a build successfully completed or failed", # the help button content | ||
2005 | 'dclass' : "span2", # indication about column width; comes from the design | ||
2006 | 'orderfield': _get_toggle_order(request, "outcome"), # adds ordering by the field value; default ascending unless clicked from ascending into descending | ||
2007 | 'ordericon':_get_toggle_order_icon(request, "outcome"), | ||
2008 | # filter field will set a filter on that column with the specs in the filter description | ||
2009 | # the class field in the filter has no relation with clclass; the control different aspects of the UI | ||
2010 | # still, it is recommended for the values to be identical for easy tracking in the generated HTML | ||
2011 | 'filter' : {'class' : 'outcome', | ||
2012 | 'label': 'Show:', | ||
2013 | 'options' : [ | ||
2014 | ('Successful builds', 'outcome:' + str(Build.SUCCEEDED), queryset_with_search.filter(outcome=str(Build.SUCCEEDED)).count()), # this is the field search expression | ||
2015 | ('Failed builds', 'outcome:'+ str(Build.FAILED), queryset_with_search.filter(outcome=str(Build.FAILED)).count()), | ||
2016 | ] | ||
2017 | } | ||
2018 | }, | ||
2019 | {'name': 'Recipe', # default column, disabled box, with just the name in the list | ||
2020 | 'qhelp': "What you built (i.e. one or more recipes or image recipes)", | ||
2021 | 'orderfield': _get_toggle_order(request, "target__target"), | ||
2022 | 'ordericon':_get_toggle_order_icon(request, "target__target"), | ||
2023 | }, | ||
2024 | {'name': 'Machine', | ||
2025 | 'qhelp': "The machine is the hardware for which you are building a recipe or image recipe", | ||
2026 | 'orderfield': _get_toggle_order(request, "machine"), | ||
2027 | 'ordericon':_get_toggle_order_icon(request, "machine"), | ||
2028 | 'dclass': 'span3' | ||
2029 | }, # a slightly wider column | ||
2030 | {'name': 'Started on', 'clclass': 'started_on', 'hidden' : 1, # this is an unchecked box, which hides the column | ||
2031 | 'qhelp': "The date and time you started the build", | ||
2032 | 'orderfield': _get_toggle_order(request, "started_on", True), | ||
2033 | 'ordericon':_get_toggle_order_icon(request, "started_on"), | ||
2034 | 'orderkey' : "started_on", | ||
2035 | 'filter' : {'class' : 'started_on', | ||
2036 | 'label': 'Show:', | ||
2037 | 'options' : [ | ||
2038 | ("Today's builds" , 'started_on__gte:'+today_begin.strftime("%Y-%m-%d"), queryset_all.filter(started_on__gte=today_begin).count()), | ||
2039 | ("Yesterday's builds", | ||
2040 | 'started_on__gte!started_on__lt:' | ||
2041 | +yesterday_begin.strftime("%Y-%m-%d")+'!' | ||
2042 | +today_begin.strftime("%Y-%m-%d"), | ||
2043 | queryset_all.filter( | ||
2044 | started_on__gte=yesterday_begin, | ||
2045 | started_on__lt=today_begin | ||
2046 | ).count()), | ||
2047 | ("Build date range", 'daterange', 1, '', 'started_on'), | ||
2048 | ] | ||
2049 | } | ||
2050 | }, | ||
2051 | {'name': 'Completed on', | ||
2052 | 'qhelp': "The date and time the build finished", | ||
2053 | 'orderfield': _get_toggle_order(request, "completed_on", True), | ||
2054 | 'ordericon':_get_toggle_order_icon(request, "completed_on"), | ||
2055 | 'orderkey' : 'completed_on', | ||
2056 | 'filter' : {'class' : 'completed_on', | ||
2057 | 'label': 'Show:', | ||
2058 | 'options' : [ | ||
2059 | ("Today's builds" , 'completed_on__gte:'+today_begin.strftime("%Y-%m-%d"), queryset_all.filter(completed_on__gte=today_begin).count()), | ||
2060 | ("Yesterday's builds", | ||
2061 | 'completed_on__gte!completed_on__lt:' | ||
2062 | +yesterday_begin.strftime("%Y-%m-%d")+'!' | ||
2063 | +today_begin.strftime("%Y-%m-%d"), | ||
2064 | queryset_all.filter( | ||
2065 | completed_on__gte=yesterday_begin, | ||
2066 | completed_on__lt=today_begin | ||
2067 | ).count()), | ||
2068 | ("Build date range", 'daterange', 1, '', 'completed_on'), | ||
2069 | ] | ||
2070 | } | ||
2071 | }, | ||
2072 | {'name': 'Failed tasks', 'clclass': 'failed_tasks', # specifing a clclass will enable the checkbox | ||
2073 | 'qhelp': "How many tasks failed during the build", | ||
2074 | 'filter' : {'class' : 'failed_tasks', | ||
2075 | 'label': 'Show:', | ||
2076 | 'options' : [ | ||
2077 | ('Builds with failed tasks', 'task_build__outcome:4', queryset_with_search.filter(task_build__outcome=4).count()), | ||
2078 | ('Builds without failed tasks', 'task_build__outcome:NOT4', queryset_with_search.filter(~Q(task_build__outcome=4)).count()), | ||
2079 | ] | ||
2080 | } | ||
2081 | }, | ||
2082 | {'name': 'Errors', 'clclass': 'errors_no', | ||
2083 | 'qhelp': "How many errors were encountered during the build (if any)", | ||
2084 | # Comment out sorting and filter until YOCTO #8131 is fixed | ||
2085 | #'orderfield': _get_toggle_order(request, "errors_no", True), | ||
2086 | #'ordericon':_get_toggle_order_icon(request, "errors_no"), | ||
2087 | #'orderkey' : 'errors_no', | ||
2088 | #'filter' : {'class' : 'errors_no', | ||
2089 | # 'label': 'Show:', | ||
2090 | # 'options' : [ | ||
2091 | # ('Builds with errors', 'errors_no__gte:1', queryset_with_search.filter(errors_no__gte=1).count()), | ||
2092 | # ('Builds without errors', 'errors_no:0', queryset_with_search.filter(errors_no=0).count()), | ||
2093 | # ] | ||
2094 | # } | ||
2095 | }, | ||
2096 | {'name': 'Warnings', 'clclass': 'warnings_no', | ||
2097 | 'qhelp': "How many warnings were encountered during the build (if any)", | ||
2098 | # Comment out sorting and filter until YOCTO #8131 is fixed | ||
2099 | #'orderfield': _get_toggle_order(request, "warnings_no", True), | ||
2100 | #'ordericon':_get_toggle_order_icon(request, "warnings_no"), | ||
2101 | #'orderkey' : 'warnings_no', | ||
2102 | #'filter' : {'class' : 'warnings_no', | ||
2103 | # 'label': 'Show:', | ||
2104 | # 'options' : [ | ||
2105 | # ('Builds with warnings','warnings_no__gte:1', queryset_with_search.filter(warnings_no__gte=1).count()), | ||
2106 | # ('Builds without warnings','warnings_no:0', queryset_with_search.filter(warnings_no=0).count()), | ||
2107 | # ] | ||
2108 | # } | ||
2109 | }, | ||
2110 | {'name': 'Time', 'clclass': 'time', 'hidden' : 1, | ||
2111 | 'qhelp': "How long it took the build to finish", | ||
2112 | # Comment out sorting until YOCTO #8131 is fixed | ||
2113 | #'orderfield': _get_toggle_order(request, "timespent", True), | ||
2114 | #'ordericon':_get_toggle_order_icon(request, "timespent"), | ||
2115 | #'orderkey' : 'timespent', | ||
2116 | }, | ||
2117 | {'name': 'Image files', 'clclass': 'output', | ||
2118 | 'qhelp': "The root file system types produced by the build. You can find them in your <code>/build/tmp/deploy/images/</code> directory", | ||
2119 | # TODO: compute image fstypes from Target_Image_File | ||
2120 | } | ||
2121 | ] | ||
2122 | } | ||
2123 | |||
2124 | # merge daterange values | ||
2125 | context.update(context_date) | ||
2126 | return context, pagesize, orderby | ||
2127 | """ | ||
2128 | |||
2129 | |||
2130 | |||
2131 | # new project | 1878 | # new project |
2132 | def newproject(request): | 1879 | def newproject(request): |
2133 | template = "newproject.html" | 1880 | template = "newproject.html" |
@@ -2829,64 +2576,6 @@ if True: | |||
2829 | 2576 | ||
2830 | return context | 2577 | return context |
2831 | 2578 | ||
2832 | # WARNING _build_list_helper() may raise a RedirectException, which | ||
2833 | # will set the GET parameters and redirect back to the | ||
2834 | # all-builds or projectbuilds page as appropriate; | ||
2835 | # TODO don't use exceptions to control program flow | ||
2836 | """ | ||
2837 | def projectbuilds(request, pid): | ||
2838 | if request.method == "POST": | ||
2839 | # process any build request | ||
2840 | |||
2841 | if 'buildCancel' in request.POST: | ||
2842 | for i in request.POST['buildCancel'].strip().split(" "): | ||
2843 | try: | ||
2844 | br = BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_QUEUED) | ||
2845 | br.state = BuildRequest.REQ_DELETED | ||
2846 | br.save() | ||
2847 | except BuildRequest.DoesNotExist: | ||
2848 | pass | ||
2849 | |||
2850 | if 'buildDelete' in request.POST: | ||
2851 | for i in request.POST['buildDelete'].strip().split(" "): | ||
2852 | try: | ||
2853 | BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_DELETED).delete() | ||
2854 | except BuildRequest.DoesNotExist: | ||
2855 | pass | ||
2856 | |||
2857 | if 'targets' in request.POST: | ||
2858 | ProjectTarget.objects.filter(project = prj).delete() | ||
2859 | s = str(request.POST['targets']) | ||
2860 | for t in s.translate(None, ";%|\"").split(" "): | ||
2861 | if ":" in t: | ||
2862 | target, task = t.split(":") | ||
2863 | else: | ||
2864 | target = t | ||
2865 | task = "" | ||
2866 | ProjectTarget.objects.create(project = prj, | ||
2867 | target = target, | ||
2868 | task = task) | ||
2869 | prj.schedule_build() | ||
2870 | |||
2871 | queryset = Build.objects.filter(project_id = pid) | ||
2872 | |||
2873 | redirect_page = resolve(request.path_info).url_name | ||
2874 | |||
2875 | context, pagesize, orderby = _build_list_helper(request, | ||
2876 | queryset, | ||
2877 | redirect_page, | ||
2878 | pid) | ||
2879 | |||
2880 | context['project'] = prj | ||
2881 | _set_parameters_values(pagesize, orderby, request) | ||
2882 | |||
2883 | # add the most recent builds for this project | ||
2884 | context['mru'] = _get_latest_builds(prj) | ||
2885 | |||
2886 | return context | ||
2887 | """ | ||
2888 | |||
2889 | |||
2890 | def _file_name_for_artifact(b, artifact_type, artifact_id): | 2579 | def _file_name_for_artifact(b, artifact_type, artifact_id): |
2891 | file_name = None | 2580 | file_name = None |
2892 | # Target_Image_File file_name | 2581 | # Target_Image_File file_name |
@@ -2962,122 +2651,3 @@ if True: | |||
2962 | 'build' : Build.objects.get(pk = build_id), | 2651 | 'build' : Build.objects.get(pk = build_id), |
2963 | } | 2652 | } |
2964 | return render(request, "unavailable_artifact.html", context) | 2653 | return render(request, "unavailable_artifact.html", context) |
2965 | |||
2966 | """ | ||
2967 | @_template_renderer("projects.html") | ||
2968 | def projects(request): | ||
2969 | (pagesize, orderby) = _get_parameters_values(request, 10, 'updated:-') | ||
2970 | mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby } | ||
2971 | retval = _verify_parameters( request.GET, mandatory_parameters ) | ||
2972 | if retval: | ||
2973 | raise RedirectException( 'all-projects', request.GET, mandatory_parameters ) | ||
2974 | |||
2975 | queryset_all = Project.objects.all() | ||
2976 | |||
2977 | # annotate each project with its number of builds | ||
2978 | queryset_all = queryset_all.annotate(num_builds=Count('build')) | ||
2979 | |||
2980 | # exclude the command line builds project if it has no builds | ||
2981 | q_default_with_builds = Q(is_default=True) & Q(num_builds__gt=0) | ||
2982 | queryset_all = queryset_all.filter(Q(is_default=False) | | ||
2983 | q_default_with_builds) | ||
2984 | |||
2985 | # boilerplate code that takes a request for an object type and returns a queryset | ||
2986 | # for that object type. copypasta for all needed table searches | ||
2987 | (filter_string, search_term, ordering_string) = _search_tuple(request, Project) | ||
2988 | queryset_with_search = _get_queryset(Project, queryset_all, None, search_term, ordering_string, '-updated') | ||
2989 | queryset = _get_queryset(Project, queryset_all, filter_string, search_term, ordering_string, '-updated') | ||
2990 | |||
2991 | # retrieve the objects that will be displayed in the table; projects a paginator and gets a page range to display | ||
2992 | project_info = _build_page_range(Paginator(queryset, pagesize), request.GET.get('page', 1)) | ||
2993 | |||
2994 | # add fields needed in JSON dumps for API call support | ||
2995 | for p in project_info.object_list: | ||
2996 | p.id = p.pk | ||
2997 | p.projectPageUrl = reverse('project', args=(p.id,)) | ||
2998 | p.layersTypeAheadUrl = reverse('xhr_layerstypeahead', args=(p.id,)) | ||
2999 | p.recipesTypeAheadUrl = reverse('xhr_recipestypeahead', args=(p.id,)) | ||
3000 | p.projectBuildsUrl = reverse('projectbuilds', args=(p.id,)) | ||
3001 | |||
3002 | # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds) | ||
3003 | build_mru = _get_latest_builds() | ||
3004 | |||
3005 | # translate the project's build target strings | ||
3006 | fstypes_map = {}; | ||
3007 | for project in project_info: | ||
3008 | try: | ||
3009 | targets = Target.objects.filter( build_id = project.get_last_build_id() ) | ||
3010 | comma = ""; | ||
3011 | extensions = ""; | ||
3012 | for t in targets: | ||
3013 | if ( not t.is_image ): | ||
3014 | continue | ||
3015 | tif = Target_Image_File.objects.filter( target_id = t.id ) | ||
3016 | for i in tif: | ||
3017 | s=re.sub('.*tar.bz2', 'tar.bz2', i.file_name) | ||
3018 | if s == i.file_name: | ||
3019 | s=re.sub('.*\.', '', i.file_name) | ||
3020 | if None == re.search(s,extensions): | ||
3021 | extensions += comma + s | ||
3022 | comma = ", " | ||
3023 | fstypes_map[project.id]=extensions | ||
3024 | except (Target.DoesNotExist,IndexError): | ||
3025 | fstypes_map[project.id]=project.get_last_imgfiles | ||
3026 | |||
3027 | context = { | ||
3028 | 'mru' : build_mru, | ||
3029 | |||
3030 | 'objects' : project_info, | ||
3031 | 'objectname' : "projects", | ||
3032 | 'default_orderby' : 'id:-', | ||
3033 | 'search_term' : search_term, | ||
3034 | 'total_count' : queryset_with_search.count(), | ||
3035 | 'fstypes' : fstypes_map, | ||
3036 | 'build_FAILED' : Build.FAILED, | ||
3037 | 'build_SUCCEEDED' : Build.SUCCEEDED, | ||
3038 | 'tablecols': [ | ||
3039 | {'name': 'Project', | ||
3040 | 'orderfield': _get_toggle_order(request, "name"), | ||
3041 | 'ordericon':_get_toggle_order_icon(request, "name"), | ||
3042 | 'orderkey' : 'name', | ||
3043 | }, | ||
3044 | {'name': 'Last activity on', | ||
3045 | 'clclass': 'updated', | ||
3046 | 'qhelp': "Shows the starting date and time of the last project build. If the project has no builds, it shows the date the project was created", | ||
3047 | 'orderfield': _get_toggle_order(request, "updated", True), | ||
3048 | 'ordericon':_get_toggle_order_icon(request, "updated"), | ||
3049 | 'orderkey' : 'updated', | ||
3050 | }, | ||
3051 | {'name': 'Release', | ||
3052 | 'qhelp' : "The version of the build system used by the project", | ||
3053 | 'orderfield': _get_toggle_order(request, "release__name"), | ||
3054 | 'ordericon':_get_toggle_order_icon(request, "release__name"), | ||
3055 | 'orderkey' : 'release__name', | ||
3056 | }, | ||
3057 | {'name': 'Machine', | ||
3058 | 'qhelp': "The hardware currently selected for the project", | ||
3059 | }, | ||
3060 | {'name': 'Number of builds', | ||
3061 | 'qhelp': "How many builds have been run for the project", | ||
3062 | }, | ||
3063 | {'name': 'Last build outcome', 'clclass': 'loutcome', | ||
3064 | 'qhelp': "Tells you if the last project build completed successfully or failed", | ||
3065 | }, | ||
3066 | {'name': 'Recipe', 'clclass': 'ltarget', | ||
3067 | 'qhelp': "The last recipe that was built in this project", | ||
3068 | }, | ||
3069 | {'name': 'Errors', 'clclass': 'lerrors', | ||
3070 | 'qhelp': "How many errors were encountered during the last project build (if any)", | ||
3071 | }, | ||
3072 | {'name': 'Warnings', 'clclass': 'lwarnings', | ||
3073 | 'qhelp': "How many warnigns were encountered during the last project build (if any)", | ||
3074 | }, | ||
3075 | {'name': 'Image files', 'clclass': 'limagefiles', 'hidden': 1, | ||
3076 | 'qhelp': "The root file system types produced by the last project build", | ||
3077 | }, | ||
3078 | ] | ||
3079 | } | ||
3080 | |||
3081 | _set_parameters_values(pagesize, orderby, request) | ||
3082 | return context | ||
3083 | """ | ||