Browse Source

Add API to access artifact metadata

ghorsington 3 years ago
parent
commit
bd984f14b5
1 changed files with 69 additions and 11 deletions
  1. 69 11
      src/app.py

+ 69 - 11
src/app.py

@@ -1,4 +1,4 @@
-from flask import Flask, render_template, abort, send_file
+from flask import Flask, render_template, abort, send_file, jsonify
 import os
 import json
 from typing import List
@@ -33,6 +33,7 @@ class Project:
     id: str
     info: ProjectInfo
 
+
     def get_artifacts(self) -> List[Artifact]:
         result = []
         artifacts_path = os.path.join("../builds", self.id, "artifacts")
@@ -41,19 +42,44 @@ class Project:
 
         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())
-                    artifact.date = artifact.date.strip()
-
-                    result.append(artifact)
-            except:
-                continue
+            artifact = self._parse_artifact(info_file_path)
+            if artifact:
+                result.append(artifact)
         return result
 
 
+    def get_lastest_artifact(self) -> Artifact:
+        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)
+        if not artifact_folders:
+            return None
+        
+        latest_artifact_folder = max(artifact_folders)
+        info_file_path = os.path.join(latest_artifact_folder, "info.json")
+        return self._parse_artifact(info_file_path)
+
+
+    def get_artifact(self, artifact_id) -> Artifact:
+        artifact_folder = os.path.join("../builds", self.id, "artifacts", artifact_id)
+        if not os.path.isdir(artifact_folder):
+            return None
+        info_file_path = os.path.join(artifact_folder, "info.json")
+        return self._parse_artifact(info_file_path)
+
+
+    def _parse_artifact(self, info_file_path):
+        if not os.path.exists(info_file_path):
+            return None
+        try:
+            with open(info_file_path, "r", encoding="utf-8") as f:
+                artifact = Artifact.from_json(f.read())
+                artifact.date = artifact.date.strip()
+                return artifact
+        except:
+            return None
+
+
 def get_projects() -> List[Project]:
     result = []
     projects = [f.path for f in os.scandir("../builds") if f.is_dir()]
@@ -72,6 +98,38 @@ def get_projects() -> List[Project]:
     return result
 
 
+@app.route("/api/projects/<string:project_id>/artifacts/latest")
+def get_latest_artifact(project_id):
+    projects = get_projects()
+
+    selected_project = next(
+        (project for project in projects if project.id == project_id), None)
+    if not selected_project:
+        return abort(404)
+
+    artifact = selected_project.get_lastest_artifact()
+    if not artifact:
+        return abort(404)
+    
+    return jsonify(artifact)
+
+
+@app.route("/api/projects/<string:project_id>/artifacts/<string:artifact_id>")
+def get_artifact_by_id(project_id, artifact_id):
+    projects = get_projects()
+
+    selected_project = next(
+        (project for project in projects if project.id == project_id), None)
+    if not selected_project:
+        return abort(404)
+
+    artifact = selected_project.get_artifact(artifact_id)
+    if not artifact:
+        return abort(404)
+    
+    return jsonify(artifact)
+
+
 @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,