Skip to contentSkip to conversation

add pages for Toaster project views

PATCH New Alex DAMIAN 1 participant 3 messages Aug 29, 2014

lore
Share & tools
lore
#0 lore raw

cover add pages for Toaster project views

From: Alexandru DAMIAN <[email protected]>

This patchset adds all the pages needed to display project views in Toaster.

The pages may have bugs, and functionality is read-only, but we need to be able to validate already existing data in the database.

Can you please merge at your convenience ?

Thanks,
Alex

The following changes since commit c2ced09e7ea4a1762d2788bb12a761734d20fd8e:

toaster: create Build methods for calculating progress and ETA (2014-08-29 13:56:39 +0100)

are available in the git repository at:

git://git.yoctoproject.org/poky-contrib adamian/20140829-submission-bb
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=adamian/20140829-submission-bb

Alexandru DAMIAN (2):
toaster: add project pages for machines, targets, layers
toastergui: added pages for project details

 lib/toaster/orm/models.py                          | 131 ++++----
 .../toastergui/templates/basebuilddetailpage.html  |   0
 .../toastergui/templates/baseprojectpage.html      |  43 +++
 lib/toaster/toastergui/templates/importlayer.html  |  68 ++++
 lib/toaster/toastergui/templates/layerdetails.html | 159 +++++++++
 lib/toaster/toastergui/templates/layers.html       |  11 +-
 lib/toaster/toastergui/templates/machines.html     |  63 ++++
 lib/toaster/toastergui/templates/project.html      | 123 +++----
 .../toastergui/templates/projectbuilds.html        |  59 ++++
 lib/toaster/toastergui/templates/projectconf.html  |  62 ++++
 lib/toaster/toastergui/templates/recipes.html      |   0
 lib/toaster/toastergui/templates/targets.html      | 186 +++++++++++
 lib/toaster/toastergui/urls.py                     |   2 +-
 lib/toaster/toastergui/views.py                    | 365 +++++++++++++++++++--
 14 files changed, 1121 insertions(+), 151 deletions(-)
 mode change 100755 => 100644 lib/toaster/toastergui/templates/basebuilddetailpage.html
 create mode 100644 lib/toaster/toastergui/templates/baseprojectpage.html
 create mode 100644 lib/toaster/toastergui/templates/importlayer.html
 create mode 100644 lib/toaster/toastergui/templates/layerdetails.html
 mode change 100755 => 100644 lib/toaster/toastergui/templates/layers.html
 create mode 100644 lib/toaster/toastergui/templates/machines.html
 create mode 100644 lib/toaster/toastergui/templates/projectbuilds.html
 create mode 100644 lib/toaster/toastergui/templates/projectconf.html
 mode change 100755 => 100644 lib/toaster/toastergui/templates/recipes.html
 create mode 100644 lib/toaster/toastergui/templates/targets.html
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/2 toaster: add project pages for machines, targets, layers

From: Alexandru DAMIAN <[email protected]>

We add new pages for the all-machines and all-targets project-related views.

We update the existing template structure to create
a base project view, similar to a base build view, that includes a breadcrumb.

Updating existing all layers view to use the new structure.

We update methods in the models to provide corrent information display.

[YOCTO #6592]
[YOCTO #6593]

---
 lib/toaster/orm/models.py                          | 131 +++++++--------
 .../toastergui/templates/basebuilddetailpage.html  |   0
 .../toastergui/templates/baseprojectpage.html      |  43 +++++
 lib/toaster/toastergui/templates/layers.html       |   9 +-
 lib/toaster/toastergui/templates/machines.html     |  63 +++++++
 lib/toaster/toastergui/templates/project.html      |  69 ++++----
 lib/toaster/toastergui/templates/recipes.html      |   0
 lib/toaster/toastergui/templates/targets.html      | 186 +++++++++++++++++++++
 lib/toaster/toastergui/views.py                    | 173 ++++++++++++++++++-
 9 files changed, 559 insertions(+), 115 deletions(-)
 mode change 100755 => 100644 lib/toaster/toastergui/templates/basebuilddetailpage.html
 create mode 100644 lib/toaster/toastergui/templates/baseprojectpage.html
 mode change 100755 => 100644 lib/toaster/toastergui/templates/layers.html
 create mode 100644 lib/toaster/toastergui/templates/machines.html
 mode change 100755 => 100644 lib/toaster/toastergui/templates/recipes.html
 create mode 100644 lib/toaster/toastergui/templates/targets.html
lib/toaster/orm/models.py +64 -67
index bb921fc..77afe35 100644
@@ -402,6 +402,18 @@ class Recipe(models.Model):
     bugtracker = models.URLField(blank=True)
     file_path = models.FilePathField(max_length=255)
 
+    def get_vcs_link_url(self):
+        if self.layer_version.layer.vcs_web_file_base_url is None:
+            return ""
+        return self.layer_version.layer.vcs_web_file_base_url.replace('%path%', self.file_path).replace('%branch%', self.layer_version.up_branch.name)
+
+    def get_layersource_view_url(self):
+        if self.layer_source is None:
+            return ""
+
+        url = self.layer_source.get_object_view(self.layer_version.up_branch, "recipes", self.name)
+        return url
+
     def __unicode__(self):
         return "Recipe " + self.name + ":" + self.version
 
@@ -508,6 +520,11 @@ class LayerIndexLayerSource(LayerSource):
         super(LayerIndexLayerSource, self).__init__(args, kwargs)
         self.sourcetype = LayerSource.TYPE_LAYERINDEX
 
+    def get_object_view(self, branch, objectype, upid):
+        if self != branch.layer_source:
+            raise Exception("Invalid branch specification")
+        return self.apiurl + "../branch/" + branch.name + "/" + objectype + "/?q=" + str(upid)
+
     def update(self):
         '''
             Fetches layer, recipe and machine information from remote repository
@@ -538,99 +555,79 @@ class LayerIndexLayerSource(LayerSource):
             return
 
         # update branches; only those that we already have names listed in the database
-        whitelist_branch_names = self.branchnames.split(",")
+        whitelist_branch_names = map(lambda x: x.name, Branch.objects.all())
 
         branches_info = _get_json_response(apilinks['branches']
             + "?filter=name:%s" % "OR".join(whitelist_branch_names))
         for bi in branches_info:
-            try:
-                b = Branch.objects.get(layer_source = self, name = bi['name'])
-                b.up_id = bi['id']
-                b.up_date = bi['updated']
-                b.name = bi['name']
-                b.bitbake_branch = bi['bitbake_branch']
-                b.short_description = bi['short_description']
-                b.save()
-            except Branch.DoesNotExist:
-                b = Branch.objects.create(
-                    layer_source = self,
-                    up_id = bi['id'],
-                    up_date = bi['updated'],
-                    name = bi['name'],
-                    bitbake_branch = bi['bitbake_branch'],
-                    short_description = bi['short_description']
-                )
+            b, created = Branch.objects.get_or_create(layer_source = self, name = bi['name'])
+            b.up_id = bi['id']
+            b.up_date = bi['updated']
+            b.name = bi['name']
+            b.bitbake_branch = bi['bitbake_branch']
+            b.short_description = bi['short_description']
+            b.save()
 
         # update layers
         layers_info = _get_json_response(apilinks['layerItems'])
         for li in layers_info:
-            try:
-                l = Layer.objects.get(layer_source = self,
-                    up_id = li['id'])
-                l.update(
-                    up_date = li['updated'],
-                    name = li['name'],
-                    vcs_url = li['vcs_url'],
-                    vcs_web_file_base_url = li['vcs_url'],
-                    summary = li['summary'],
-                    description = li['description'])
-            except Layer.DoesNotExist:
-                Layer.objects.create(layer_source = self,
-                    up_id = li['id'],
-                    up_date = li['updated'],
-                    name = li['name'],
-                    vcs_url = li['vcs_url'],
-                    vcs_web_file_base_url = li['vcs_url'],
-                    summary = li['summary'],
-                    description = li['description']
-                )
+            l, created = Layer.objects.get_or_create(layer_source = self, up_id = li['id'])
+            l.up_date = li['updated']
+            l.name = li['name']
+            l.vcs_url = li['vcs_url']
+            l.vcs_web_file_base_url = li['vcs_web_file_base_url']
+            l.summary = li['summary']
+            l.description = li['description']
+            l.save()
 
         # update layerbranches/layer_versions
         layerbranches_info = _get_json_response(apilinks['layerBranches']
                 + "?filter=branch:%s" % "OR".join(map(lambda x: str(x.up_id), Branch.objects.filter(layer_source = self)))
             )
         for lbi in layerbranches_info:
-            Layer_Version.objects.get_or_create(layer_source = self,
-                    up_id = lbi['id'],
-                    up_date = lbi['updated'],
-                    layer = Layer.objects.get(layer_source = self, up_id = lbi['layer']),
-                    up_branch = Branch.objects.get(layer_source = self, up_id = lbi['branch']),
-                    branch = lbi['actual_branch'],
-                    commit = lbi['vcs_last_rev'],
-                    dirpath = lbi['vcs_subdir'])
+            lv, created = Layer_Version.objects.get_or_create(layer_source = self, up_id = lbi['id'])
+
+            lv.up_date = lbi['updated']
+            lv.layer = Layer.objects.get(layer_source = self, up_id = lbi['layer'])
+            lv.up_branch = Branch.objects.get(layer_source = self, up_id = lbi['branch'])
+            lv.branch = lbi['actual_branch']
+            lv.commit = lbi['vcs_last_rev']
+            lv.dirpath = lbi['vcs_subdir']
+            lv.save()
+
 
         # update machines
         machines_info = _get_json_response(apilinks['machines']
                 + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self)))
             )
         for mi in machines_info:
-            Machine.objects.get_or_create(layer_source = self,
-                    up_id = mi['id'],
-                    up_date = mi['updated'],
-                    layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch']),
-                    name = mi['name'],
-                    description = mi['description'])
+            mo, created = Machine.objects.get_or_create(layer_source = self, up_id = mi['id'])
+            mo.up_date = mi['updated']
+            mo.layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch'])
+            mo.name = mi['name']
+            mo.description = mi['description']
+            mo.save()
 
         # update recipes; paginate by layer version / layer branch
         recipes_info = _get_json_response(apilinks['recipes']
                 + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self)))
             )
         for ri in recipes_info:
-            Recipe.objects.get_or_create(layer_source = self,
-                    up_id = ri['id'],
-                    up_date = ri['updated'],
-                    layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch']),
-
-                    name = ri['pn'],
-                    version = ri['pv'],
-                    summary = ri['summary'],
-                    description = ri['description'],
-                    section = ri['section'],
-                    license = ri['license'],
-                    homepage = ri['homepage'],
-                    bugtracker = ri['bugtracker'],
-                    file_path = ri['filepath'] + ri['filename']
-                )
+            ro, created = Recipe.objects.get_or_create(layer_source = self, up_id = ri['id'])
+
+            ro.up_date = ri['updated']
+            ro.layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch'])
+
+            ro.name = ri['pn']
+            ro.version = ri['pv']
+            ro.summary = ri['summary']
+            ro.description = ri['description']
+            ro.section = ri['section']
+            ro.license = ri['license']
+            ro.homepage = ri['homepage']
+            ro.bugtracker = ri['bugtracker']
+            ro.file_path = ri['filepath'] + ri['filename']
+            ro.save()
 
         pass
 
lib/toaster/toastergui/templates/basebuilddetailpage.html +0 -0
old mode 100755
new mode 100644
lib/toaster/toastergui/templates/baseprojectpage.html new file +43 -0

43 lines not on this page · raw message

lib/toaster/toastergui/templates/layers.html +7 -2
old mode 100755
new mode 100644
index d7d159e..bc6e5a3
@@ -1,7 +1,12 @@
-{% extends "base.html" %}
+{% extends "baseprojectpage.html" %}
 {% load projecttags %}
 {% load humanize %}
-{% block pagecontent %}
+
+{% block localbreadcrumb %}
+<li>Layers</li>
+{% endblock %}
+
+{% block projectinfomain %}
                 <div class="page-header">
                     <h1>
                         All layers
lib/toaster/toastergui/templates/machines.html new file +63 -0

63 lines not on this page · raw message

lib/toaster/toastergui/templates/project.html +29 -40

92 lines not on this page · raw message

lib/toaster/toastergui/templates/recipes.html +0 -0
old mode 100755
new mode 100644
lib/toaster/toastergui/templates/targets.html new file +186 -0

186 lines not on this page · raw message

lib/toaster/toastergui/views.py +167 -6

231 lines not on this page · raw message

Signature · 1 line
1.9.1
#2 lore raw

PATCH 2/2 toastergui: added pages for project details

From: Alexandru DAMIAN <[email protected]>

We add new pages for the layer importing, layer details, showing project builds and project configuration.

The pages are in read-only mode, but they're needed as to be able to verify the quality of data in the system.

Write capabilities will be added in a subsequent patch.

[YOCTO #6595]
[YOCTO #6590]
[YOCTO #6591]
[YOCTO #6588]
[YOCTO #6589]

---
 lib/toaster/toastergui/templates/importlayer.html  |  68 ++++++++
 lib/toaster/toastergui/templates/layerdetails.html | 159 +++++++++++++++++
 lib/toaster/toastergui/templates/layers.html       |   2 +-
 lib/toaster/toastergui/templates/project.html      |  58 ++++---
 .../toastergui/templates/projectbuilds.html        |  59 +++++++
 lib/toaster/toastergui/templates/projectconf.html  |  62 +++++++
 lib/toaster/toastergui/urls.py                     |   2 +-
 lib/toaster/toastergui/views.py                    | 192 +++++++++++++++++++--
 8 files changed, 564 insertions(+), 38 deletions(-)
 create mode 100644 lib/toaster/toastergui/templates/importlayer.html
 create mode 100644 lib/toaster/toastergui/templates/layerdetails.html
 create mode 100644 lib/toaster/toastergui/templates/projectbuilds.html
 create mode 100644 lib/toaster/toastergui/templates/projectconf.html
lib/toaster/toastergui/templates/importlayer.html new file +68 -0
new file mode 100644
index 0000000..7e48eac
@@ -0,0 +1,68 @@
+{% extends "baseprojectpage.html" %}
+{% load projecttags %}
+{% load humanize %}
+
+{% block localbreadcrumb %}
+<li>Layers</li>
+{% endblock %}
+
+{% block projectinfomain %}
+                <div class="page-header">
+                    <h1>Import layer</h1>
+                </div>
+                <form>
+        {% if project %}
+                    <span class="help-block" style="padding-left:19px;">The layer you are importing must be compatible with {{project.release.name}} ({{project.release.description}}), which is the release you are using in this project.</span>
+          {% endif %}
+                    <fieldset class="air">
+                        <legend>Layer repository information</legend>
+                        <label>
+                            Git repository URL
+                            <i class="icon-question-sign get-help" title="Fetch/clone URL of the repository. Currently, Toaster only supports Git repositories."></i>
+                        </label>
+                        <input id="repo" type="text" class="input-xxlarge" required>
+                        <label class="project-form">
+                            Repository subdirectory
+                            <span class="muted">(optional)</span>
+                            <i class="icon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></i>
+                        </label>
+                        <input type="text"  id="subdir">
+                        <label class="project-form">Branch, tag or commit</label>
+                        <input type="text" class="span4" id="layer-version" required>
+                        <label class="project-form">
+                            Layer name
+                            <i class="icon-question-sign get-help" title="Something like 'meta-mylayer'. Your layer name must be unique and can only include letters, numbers and dashes"></i>
+                        </label>
+                        <input id="layer-name" type="text" required>
+                    </fieldset>
+                    <fieldset class="air">
+                        <legend>
+                            Layer dependencies
+                            <span class="muted">(optional)</span>
+                            <i class="icon-question-sign get-help heading-help" title="Other layers this layer depends upon"></i>
+                        </legend>
+                        <ul class="unstyled configuration-list">
+                            <li>
+                                <a href="" class="layer-info" title="OpenEmbedded | daisy">openembedded-core (meta)</a>
+                                <i class="icon-trash"></i>
+                            </li>
+                        </ul>
+                        <div class="input-append">
+                            <input type="text" autocomplete="off" data-minLength="1" data-autocomplete="off"
+                            data-provide="typeahead"  data-source='
+                []
+                ' placeholder="Type a layer name" id="layer-dependency" class="input-xlarge">
+                            <a class="btn" type="button" id="add-layer-dependency" disabled>
+                                Add layer
+                            </a>
+                        </div>
+                        <span class="help-inline">You can only add layers Toaster knows about</span>
+                    </fieldset>
+                    <div class="form-actions">
+                        <a href="#dependencies-message" class="btn btn-primary btn-large" data-toggle="modal" data-target="#dependencies-message" disabled>Import and add to project</a>
+                        <a href="layer-details-just-imported.html" class="btn btn-large" disabled>Just import for the moment</a>
+                        <span class="help-inline" style="vertical-align: middle;">To import a layer, you need to enter a repository URL, a branch, tag or commit and a layer name</span>
+                    </div>
+                </form>
+
+{% endblock %}
lib/toaster/toastergui/templates/layerdetails.html new file +159 -0

159 lines not on this page · raw message

lib/toaster/toastergui/templates/layers.html +1 -1
index bc6e5a3..281b72a 100644
@@ -33,7 +33,7 @@
 {% include "basetable_top.html" %}
     {% for lv in objects %}
     <tr class="data">
-            <td class="layer">{{lv.layer.name}}</td>
+            <td class="layer"><a href="{% url 'layerdetails' lv.id %}">{{lv.layer.name}}</a></td>
             <td class="description">{{lv.layer.summary}}</td>
             <td class="source"><a href="{% url 'layerdetails' lv.pk %}">{{lv.layer_source.name}}</a></td>
             <td class="git-repo"><a href="{% url 'layerdetails' lv.pk %}"><code>{{lv.layer.layer_index_url}}</code></a></td>
lib/toaster/toastergui/templates/project.html +35 -23

98 lines not on this page · raw message

lib/toaster/toastergui/templates/projectbuilds.html new file +59 -0

59 lines not on this page · raw message

lib/toaster/toastergui/templates/projectconf.html new file +62 -0

62 lines not on this page · raw message

lib/toaster/toastergui/urls.py +1 -1
index 30f0063..a9c0592 100644
@@ -76,7 +76,7 @@ urlpatterns = patterns('toastergui.views',
 
         url(r'^project/(?P<pid>\d+)/$', 'project', name='project'),
         url(r'^project/(?P<pid>\d+)/configuration$', 'projectconf', name='projectconf'),
-        url(r'^project/(?P<pid>\d+)/builds$', 'projectbuilds', name='projectbuild'),
+        url(r'^project/(?P<pid>\d+)/builds$', 'projectbuilds', name='projectbuilds'),
 
         url(r'^xhr_projectbuild/(?P<pid>\d+)/$', 'xhr_projectbuild', name='xhr_projectbuild'),
         url(r'^xhr_projectedit/(?P<pid>\d+)/$', 'xhr_projectedit', name='xhr_projectedit'),
lib/toaster/toastergui/views.py +179 -13

233 lines not on this page · raw message

Signature · 1 line
1.9.1