Quellcode durchsuchen

Implement artifacts view

ghorsington vor 5 Jahren
Ursprung
Commit
b79cc7bf9d
4 geänderte Dateien mit 113 neuen und 39 gelöschten Zeilen
  1. 59 3
      src/app.py
  2. 7 0
      src/static/script/artifacts.js
  3. 1 0
      src/templates/base.html
  4. 46 36
      src/templates/project_view.html

+ 59 - 3
src/app.py

@@ -1,4 +1,4 @@
-from flask import Flask, render_template, abort
+from flask import Flask, render_template, abort, send_file
 from flask_assets import Environment, Bundle
 import os
 import json
@@ -18,6 +18,34 @@ assets.config['PYSCSS_ASSETS_ROOT'] = assets.directory
 assets.register('scss_all', scss)
 
 
+class ArtifactItem:
+    file: str
+    description: str
+
+    def __init__(self, file, description):
+        self.file = file
+        self.description = description
+
+
+class Artifact:
+    id: str
+    date: str
+    changelog: str
+    artifacts: List[ArtifactItem]
+
+    def __init__(self, id, date, changelog, artifacts):
+        self.id = id
+        self.date = date
+        self.changelog = changelog
+        self.artifacts = [ArtifactItem(**item)
+                          for item in artifacts]
+
+    @classmethod
+    def from_json(cls, json_str):
+        json_dict = json.loads(json_str)
+        return cls(**json_dict)
+
+
 class ProjectInfo:
     name: str
 
@@ -34,6 +62,24 @@ class Project:
     id: str
     info: ProjectInfo
 
+    def get_artifacts(self) -> List[Artifact]:
+        result = []
+        artifacts_path = os.path.join("../builds", self.id, "artifacts")
+        artifact_folders = sorted([folder.path for folder in os.scandir(
+            artifacts_path) if folder.is_dir()], reverse=True)
+
+        for artifact_folder in artifact_folders:
+            info_file_path = os.path.join(artifact_folder, "info.json")
+            if not os.path.exists(info_file_path):
+                continue
+            try:
+                with open(info_file_path, "r", encoding="utf-8") as f:
+                    artifact = Artifact.from_json(f.read())
+                    result.append(artifact)
+            except:
+                continue
+        return result
+
 
 def get_projects() -> List[Project]:
     result = []
@@ -53,6 +99,15 @@ def get_projects() -> List[Project]:
     return result
 
 
+@app.route("/projects/<string:project_id>/<string:artifact_id>/<string:download_item>")
+def download_item(project_id, artifact_id, download_item):
+    file_path = os.path.join("../builds", project_id,
+                             "artifacts", artifact_id, download_item)
+    if not os.path.exists(file_path):
+        return abort(404)
+    return send_file(file_path)
+
+
 @app.route("/projects/<string:project_id>")
 def display_project(project_id):
     projects = get_projects()
@@ -63,7 +118,6 @@ def display_project(project_id):
         return abort(404)
 
     info_path = os.path.join("../builds", selected_project.id, "info.md")
-
     readme = None
     try:
         if os.path.exists(info_path):
@@ -72,7 +126,9 @@ def display_project(project_id):
     except:
         readme = None
 
-    return render_template("project_view.html", projects=projects, selected_project=selected_project, readme=readme)
+    artifacts = selected_project.get_artifacts()
+
+    return render_template("project_view.html", projects=projects, selected_project=selected_project, readme=readme, artifacts=artifacts)
 
 
 @app.route("/")

+ 7 - 0
src/static/script/artifacts.js

@@ -0,0 +1,7 @@
+$(() => {
+    $("div.artifact-item").on("click", "div.artifact-details", e => {
+        e.preventDefault();
+        let $artifact = $(e.delegateTarget);
+        $artifact.children("div.artifact-contents").toggle();
+    });
+});

+ 1 - 0
src/templates/base.html

@@ -10,6 +10,7 @@
     {% endassets %}
     <script src="{{ url_for('static', filename='script/jquery-3.4.1.min.js') }}"></script>
     <script src="https://kit.fontawesome.com/9ba4c07aa0.js" crossorigin="anonymous"></script>
+    {%block head%}{%endblock%}
     <title>BepisBuilds - {% block title %}{% endblock %}</title>
 </head>
 

+ 46 - 36
src/templates/project_view.html

@@ -1,5 +1,9 @@
 {% extends "base.html" %}
 
+{%block head%}
+<script src="{{ url_for('static', filename='script/artifacts.js') }}"></script>
+{%endblock%}
+
 {%block title%}{{selected_project.info.name}}{%endblock%}
 
 {%block content%}
@@ -18,46 +22,52 @@
 </div>
 
 
-<div>
-    <h1 class="is-size-3">Artifacts</h1>
-
-    <div class="artifact-item">
-        <div class="artifact-details">
-            <div class="artifact-id">
-                <p class="is-size-5">#120</p>
-            </div>
-            <div class="artifact-info">
-                <div class="artifact-info-content" style="align-items: center">
-                    <p>Build date:</p>
-                    <div class="dropdown-button">
-                        <i class="fas fa-chevron-down fa-lg"></i>
-                    </div>
+<h1 class="is-size-3">Artifacts</h1>
+{%-for artifact in artifacts %}
+<div class="artifact-item">
+    <div class="artifact-details">
+        <div class="artifact-id">
+            <p class="is-size-5">#{{artifact.id}}</p>
+        </div>
+        <div class="artifact-info">
+            <div class="artifact-info-content" style="align-items: center">
+                <p>Build date: {{artifact.date}}</p>
+                <div class="dropdown-button">
+                    <i class="fas fa-chevron-down fa-lg"></i>
                 </div>
             </div>
         </div>
-        <div class="artifact-contents">
-            <div class="column content is-small">
-                <h2>Downloads</h2>
-
-                <div>
-                    <table class="table is-hoverable is-striped is-bordered is-narrow">
-                        <thead>
-                            <tr>
-                                <th>Artifact</th>
-                                <th>Description</th>
-                            </tr>
-                        </thead>
-                        <tbody>
-                            <tr>
-                                <td><a class="button is-link">asdasd</a></td>
-                                <td>adasdsd</td>
-                            </tr>
-                        </tbody>
-                    </table>
-                </div>
-                <h2>Changelog</h2>
+    </div>
+    <div class="artifact-contents" style="display: none">
+        <div class="column content is-small">
+            <h2>Downloads</h2>
+
+            <div>
+                <table class="table is-hoverable is-striped is-bordered is-narrow">
+                    <thead>
+                        <tr>
+                            <th>Artifact</th>
+                            <th>Description</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        {%-for download_item in artifact.artifacts%}
+                        <tr>
+                            <td><a class="button is-link" href="{{ url_for('download_item', project_id=selected_project.id, artifact_id=artifact.id, download_item=download_item.file)}}">{{download_item.file}}</a></td>
+                            <td>{{download_item.description}}</td>
+                        </tr>
+                        {%-endfor%}
+                    </tbody>
+                </table>
             </div>
+            <h2>Changelog</h2>
+            <p>
+                {{artifact.changelog|safe}}
+            </p>
         </div>
     </div>
 
-    {%endblock%}
+</div>
+{%-endfor%}
+
+{%endblock%}