0.3.0: Bug-fixes & cleanup (#34)
Add 'description' to entry Fixes #26, fixes #25 General cleanup
This commit is contained in:
parent
19e625ad27
commit
c2d55b2ca0
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2022 Ethan Roseman
|
Copyright (c) 2023 Ethan Roseman
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -1,311 +0,0 @@
|
||||||
#! /usr/bin/env python3
|
|
||||||
import argparse
|
|
||||||
import csv
|
|
||||||
from io import FileIO, StringIO
|
|
||||||
import json
|
|
||||||
import requests
|
|
||||||
from typing import Iterable, List, Any, Dict
|
|
||||||
|
|
||||||
BASE_URL = "http://127.0.0.1:8000/data"
|
|
||||||
|
|
||||||
|
|
||||||
def make_slug_url(args: argparse.Namespace) -> str:
|
|
||||||
if BASE_URL:
|
|
||||||
url_components = [BASE_URL]
|
|
||||||
else:
|
|
||||||
url_components = [args.base_url]
|
|
||||||
|
|
||||||
for arg in [args.project, args.version, args.category]:
|
|
||||||
if arg != "":
|
|
||||||
url_components.append(arg)
|
|
||||||
|
|
||||||
return str.join("/", url_components)
|
|
||||||
|
|
||||||
|
|
||||||
def make_url_options(args: argparse.Namespace) -> str:
|
|
||||||
options: List[str] = []
|
|
||||||
|
|
||||||
if args.all:
|
|
||||||
options += "all=true"
|
|
||||||
|
|
||||||
ret = str.join("&", options)
|
|
||||||
if ret != "":
|
|
||||||
return "?" + ret
|
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def make_url(args: argparse.Namespace) -> str:
|
|
||||||
url = make_slug_url(args)
|
|
||||||
url += make_url_options(args)
|
|
||||||
return url
|
|
||||||
|
|
||||||
|
|
||||||
# def dict_filter(input: list, *keys) -> dict:
|
|
||||||
# output: list = []
|
|
||||||
# for d in input:
|
|
||||||
# output.append(dict((k, d[k]) for k in keys))
|
|
||||||
# return output
|
|
||||||
|
|
||||||
|
|
||||||
fields = [
|
|
||||||
"csv_version",
|
|
||||||
"timestamp",
|
|
||||||
"git_hash",
|
|
||||||
"code_matching",
|
|
||||||
"code_total",
|
|
||||||
"boot/matching",
|
|
||||||
"boot/total",
|
|
||||||
"code/matching",
|
|
||||||
"code/total",
|
|
||||||
"overlays/matching",
|
|
||||||
"overlays/total",
|
|
||||||
"asm",
|
|
||||||
"nonmatching_functions_count",
|
|
||||||
"assets_identified",
|
|
||||||
"assets_total",
|
|
||||||
"archives/identified",
|
|
||||||
"archives/total",
|
|
||||||
"audio/identified",
|
|
||||||
"audio/total",
|
|
||||||
"interface/identified",
|
|
||||||
"interface/total",
|
|
||||||
"misc/identified",
|
|
||||||
"misc/total",
|
|
||||||
"objects/identified",
|
|
||||||
"objects/total",
|
|
||||||
"scenes/identified",
|
|
||||||
"scenes/total",
|
|
||||||
"text/identified",
|
|
||||||
"text/total",
|
|
||||||
]
|
|
||||||
extra_fields = [
|
|
||||||
"csv_version",
|
|
||||||
"timestamp",
|
|
||||||
"git_hash",
|
|
||||||
"code_decompiled",
|
|
||||||
"code_total",
|
|
||||||
"boot/decompiled",
|
|
||||||
"boot/total",
|
|
||||||
"code/decompiled",
|
|
||||||
"code/total",
|
|
||||||
"overlays/decompiled",
|
|
||||||
"overlays/total",
|
|
||||||
"asm",
|
|
||||||
"nonmatching_functions_count",
|
|
||||||
"assets_debinarised",
|
|
||||||
"assets_total",
|
|
||||||
"archives/debinarised",
|
|
||||||
"archives/total",
|
|
||||||
"audio/debinarised",
|
|
||||||
"audio/total",
|
|
||||||
"interface/debinarised",
|
|
||||||
"interface/total",
|
|
||||||
"misc/debinarised",
|
|
||||||
"misc/total",
|
|
||||||
"objects/debinarised",
|
|
||||||
"objects/total",
|
|
||||||
"scenes/debinarised",
|
|
||||||
"scenes/total",
|
|
||||||
"text/debinarised",
|
|
||||||
"text/total",
|
|
||||||
]
|
|
||||||
|
|
||||||
categories = [
|
|
||||||
"default",
|
|
||||||
"boot",
|
|
||||||
"code",
|
|
||||||
"overlays",
|
|
||||||
"assets",
|
|
||||||
"archives",
|
|
||||||
"audio",
|
|
||||||
"interface",
|
|
||||||
"misc",
|
|
||||||
"objects",
|
|
||||||
"scenes",
|
|
||||||
"text",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def double_csv_to_json(
|
|
||||||
input: Iterable[str], extra_input: Iterable[str], output: List[Any]
|
|
||||||
) -> None:
|
|
||||||
csv_reader = csv.DictReader(input, fields)
|
|
||||||
extra_csv_reader = csv.DictReader(extra_input, extra_fields)
|
|
||||||
|
|
||||||
for row in csv_reader:
|
|
||||||
new_row: Dict[str, Any] = {}
|
|
||||||
for field in row:
|
|
||||||
measure = str.split(field, "/")
|
|
||||||
category = measure[0]
|
|
||||||
if category in categories:
|
|
||||||
if category not in new_row:
|
|
||||||
new_row[category] = {}
|
|
||||||
new_row[category][measure[1]] = int(row[field])
|
|
||||||
elif category in ["csv_version"]:
|
|
||||||
continue
|
|
||||||
elif category in ["git_hash"]:
|
|
||||||
new_row[category] = row.get(field)
|
|
||||||
elif category in ["timestamp"]:
|
|
||||||
new_row[category] = int(row[field])
|
|
||||||
else:
|
|
||||||
if "default" not in new_row:
|
|
||||||
new_row["default"] = {}
|
|
||||||
new_row["default"][category] = int(row[field])
|
|
||||||
|
|
||||||
if extra_input:
|
|
||||||
# For brevity this makes assumptions about the categories being present in the primary
|
|
||||||
extra_row: Dict[str, Any] = extra_csv_reader.__next__()
|
|
||||||
for field in extra_row:
|
|
||||||
measure = str.split(field, "/")
|
|
||||||
category = measure[0]
|
|
||||||
if category in categories:
|
|
||||||
if category not in new_row:
|
|
||||||
new_row[category] = {}
|
|
||||||
if measure[1] not in new_row[category]:
|
|
||||||
new_row[category][measure[1]] = int(extra_row[field])
|
|
||||||
elif category in ["csv_version", "timestamp", "git_hash"]:
|
|
||||||
continue
|
|
||||||
# new_row[category] = row.get(field)
|
|
||||||
else:
|
|
||||||
if "default" not in new_row:
|
|
||||||
new_row["default"] = {}
|
|
||||||
if category not in new_row["default"]:
|
|
||||||
new_row["default"][category] = int(extra_row[field])
|
|
||||||
|
|
||||||
output.append(new_row)
|
|
||||||
|
|
||||||
# filter_fields = [
|
|
||||||
# "timestamp",
|
|
||||||
# "git_hash",
|
|
||||||
# "matching_bytes",
|
|
||||||
# "total_bytes",
|
|
||||||
# ]
|
|
||||||
# output = dict_filter(output, filter_fields)
|
|
||||||
# print(output)
|
|
||||||
|
|
||||||
|
|
||||||
# def confuse_dicts(input, output: dict):
|
|
||||||
# mid = []
|
|
||||||
# for row in input:
|
|
||||||
# newRow = {}
|
|
||||||
# for category in categories:
|
|
||||||
# newRow[category] = {}
|
|
||||||
# for field in ["timestamp", "git_hash"]:
|
|
||||||
# newRow[category][field] = row.get(field)
|
|
||||||
# for field in row.get(category):
|
|
||||||
# newRow[category][field] = row.get(category).get(field)
|
|
||||||
# mid.append(newRow)
|
|
||||||
|
|
||||||
# for category in categories:
|
|
||||||
# output[category] = []
|
|
||||||
# for row in mid:
|
|
||||||
# output[category].append(row.get(category))
|
|
||||||
|
|
||||||
|
|
||||||
# def csv_to_category_json(args: argparse.Namespace, input):
|
|
||||||
# ...
|
|
||||||
|
|
||||||
|
|
||||||
test_csv_input = """
|
|
||||||
2,1615435438,e788bfecbfb10afd4182332db99bb562ea75b1de,103860,4747584,31572,86064,58624,1065936,13664,3595584,4597948,49,0,40816656,0,434608,0,6029280,0,801520,0,3900928,0,13518304,0,15695712,0,436304
|
|
||||||
2,1660614141,bb96e47f8df9fa42e2120b7acda90432bacfde39,3143604,4747584,78172,86064,507828,1065936,2557604,3595584,1613196,31,3592092,40816656,0,434608,0,6029280,80976,801520,328616,3900928,3146908,13518304,35592,15695712,0,436304
|
|
||||||
"""
|
|
||||||
|
|
||||||
test_extra_csv_input = """
|
|
||||||
2,1615435438,e788bfecbfb10afd4182332db99bb562ea75b1de,120152,4747584,36352,86064,70136,1065936,13664,3595584,4582152,0,0,40816656,0,434608,0,6029280,0,801520,0,3900928,0,13518304,0,15695712,0,436304
|
|
||||||
2,1660614141,bb96e47f8df9fa42e2120b7acda90432bacfde39,3177404,4747584,78544,86064,522780,1065936,2576080,3595584,1579396,0,29774016,40816656,0,434608,0,6029280,80976,801520,479024,3900928,13518304,13518304,15695712,15695712,0,436304
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
description = "Talk to frogress."
|
|
||||||
epilog = ""
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description=description,
|
|
||||||
epilog=epilog,
|
|
||||||
formatter_class=argparse.RawTextHelpFormatter,
|
|
||||||
)
|
|
||||||
# parser.add_argument("base_url", help="")
|
|
||||||
parser.add_argument("-p", "--project", help="", default="")
|
|
||||||
parser.add_argument("-v", "--version", help="", default="")
|
|
||||||
parser.add_argument("-c", "--category", help="", default="")
|
|
||||||
parser.add_argument(
|
|
||||||
"-a",
|
|
||||||
"--all",
|
|
||||||
help="fetch history instead of just most recent entry",
|
|
||||||
action="store_true",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
url = make_url(args)
|
|
||||||
url += "/"
|
|
||||||
url += "?format=json"
|
|
||||||
print(url)
|
|
||||||
|
|
||||||
# with requests.get(url) as r:
|
|
||||||
# print(r.status_code)
|
|
||||||
# if r.status_code == 200:
|
|
||||||
# result = r.json()
|
|
||||||
# try:
|
|
||||||
# string = json.dumps(result, sort_keys=True, indent=4)
|
|
||||||
# print(string)
|
|
||||||
# except:
|
|
||||||
# print("No idea what this package thought was wrong")
|
|
||||||
|
|
||||||
# result = subprocess.run(["curl", "-s", url], stdout=subprocess.PIPE)
|
|
||||||
# print(result.stdout)
|
|
||||||
# print(result)
|
|
||||||
# try:
|
|
||||||
# data = json.loads(result.stdout.decode())
|
|
||||||
# string = json.dumps(data, sort_keys=True, indent=4)
|
|
||||||
# print(string)
|
|
||||||
# except:
|
|
||||||
# print("Malformed JSON returned, is this URL not implemented yet?")
|
|
||||||
|
|
||||||
# with StringIO(test_csv_input) as f:
|
|
||||||
# output = []
|
|
||||||
# csv_to_json(f, output)
|
|
||||||
# # for entry in output:
|
|
||||||
# # string = json.dumps(entry, indent=4)
|
|
||||||
# # print(string)
|
|
||||||
|
|
||||||
# # confused_output = []
|
|
||||||
# # confuse_dicts(output, confused_output)
|
|
||||||
# # for entry in confused_output:
|
|
||||||
# # string = json.dumps(entry, indent=4)
|
|
||||||
# # print(string)
|
|
||||||
# confused_output = {}
|
|
||||||
# confuse_dicts(output, confused_output)
|
|
||||||
# string = json.dumps(confused_output, indent=4)
|
|
||||||
# print(string)
|
|
||||||
|
|
||||||
with StringIO(test_csv_input) as f:
|
|
||||||
with StringIO(test_extra_csv_input) as g:
|
|
||||||
output: List[Any] = []
|
|
||||||
double_csv_to_json(f, g, output)
|
|
||||||
request_body = {"api_key": "2", "data": output}
|
|
||||||
string = json.dumps(request_body, indent=4)
|
|
||||||
print(request_body)
|
|
||||||
# for entry in output:
|
|
||||||
# string = json.dumps(entry, indent=4)
|
|
||||||
# print(string)
|
|
||||||
|
|
||||||
# confused_output = []
|
|
||||||
# confuse_dicts(output, confused_output)
|
|
||||||
# for entry in confused_output:
|
|
||||||
# string = json.dumps(entry, indent=4)
|
|
||||||
# print(string)
|
|
||||||
# confused_output = {}
|
|
||||||
# confuse_dicts(output, confused_output)
|
|
||||||
# string = json.dumps(confused_output, indent=4)
|
|
||||||
# print(string)
|
|
||||||
|
|
||||||
with requests.post(url, json=request_body) as r:
|
|
||||||
print(r.status_code)
|
|
||||||
print(r.text)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -1,87 +0,0 @@
|
||||||
#! /usr/bin/env python3
|
|
||||||
import argparse
|
|
||||||
import requests
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
BASE_URL = "http://127.0.0.1:8000/projects"
|
|
||||||
|
|
||||||
|
|
||||||
def make_slug_url(args: argparse.Namespace) -> str:
|
|
||||||
if BASE_URL:
|
|
||||||
url_components = [BASE_URL]
|
|
||||||
else:
|
|
||||||
url_components = [args.base_url]
|
|
||||||
|
|
||||||
for arg in [args.project, args.version]:
|
|
||||||
if arg != "":
|
|
||||||
url_components.append(arg)
|
|
||||||
|
|
||||||
return str.join("/", url_components)
|
|
||||||
|
|
||||||
|
|
||||||
def make_url_options(args: argparse.Namespace) -> str:
|
|
||||||
options: List[str] = []
|
|
||||||
|
|
||||||
ret = str.join("&", options)
|
|
||||||
if ret != "":
|
|
||||||
return "?" + ret
|
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def make_url(args: argparse.Namespace) -> str:
|
|
||||||
url = make_slug_url(args)
|
|
||||||
url += make_url_options(args)
|
|
||||||
return url
|
|
||||||
|
|
||||||
|
|
||||||
categories = [
|
|
||||||
# "default",
|
|
||||||
# "boot",
|
|
||||||
# "code",
|
|
||||||
# "overlays",
|
|
||||||
"assets",
|
|
||||||
"archives",
|
|
||||||
"audio",
|
|
||||||
"interface",
|
|
||||||
"misc",
|
|
||||||
"objects",
|
|
||||||
"scenes",
|
|
||||||
"text",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
description = "Make categories."
|
|
||||||
epilog = ""
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description=description,
|
|
||||||
epilog=epilog,
|
|
||||||
formatter_class=argparse.RawTextHelpFormatter,
|
|
||||||
)
|
|
||||||
# parser.add_argument("base_url", help="")
|
|
||||||
parser.add_argument("-p", "--project", help="", default="")
|
|
||||||
parser.add_argument("-v", "--version", help="", default="")
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
url = make_url(args)
|
|
||||||
url += "/"
|
|
||||||
url += "?format=json"
|
|
||||||
print(url)
|
|
||||||
|
|
||||||
request_data = {}
|
|
||||||
for cat in categories:
|
|
||||||
request_data[cat] = cat.capitalize()
|
|
||||||
|
|
||||||
request_json = {"api_key": "2", "categories": request_data}
|
|
||||||
|
|
||||||
print(request_json)
|
|
||||||
|
|
||||||
with requests.post(url, json=request_json) as r:
|
|
||||||
print(r.status_code)
|
|
||||||
print(r.text)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -11,7 +11,6 @@ RUN echo 'export PATH="/etc/poetry/bin:$PATH"' > /root/.bashrc
|
||||||
|
|
||||||
RUN mkdir /frogress
|
RUN mkdir /frogress
|
||||||
|
|
||||||
COPY consumer_scripts /frogress/consumer_scripts
|
|
||||||
COPY frog_api /frogress/frog_api
|
COPY frog_api /frogress/frog_api
|
||||||
COPY frogress /frogress/frogress
|
COPY frogress /frogress/frogress
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@ class NonexistentProjectException(APIException):
|
||||||
status_code = status.HTTP_404_NOT_FOUND
|
status_code = status.HTTP_404_NOT_FOUND
|
||||||
|
|
||||||
def __init__(self, project: str):
|
def __init__(self, project: str):
|
||||||
super().__init__(f"Project {project} not found")
|
super().__init__(f"Project {project} does not exist")
|
||||||
|
|
||||||
|
|
||||||
class NonexistentVersionException(APIException):
|
class NonexistentVersionException(APIException):
|
||||||
status_code = status.HTTP_404_NOT_FOUND
|
status_code = status.HTTP_404_NOT_FOUND
|
||||||
|
|
||||||
def __init__(self, project: str, version: str):
|
def __init__(self, project: str, version: str):
|
||||||
super().__init__(f"Version '{version}' for project '{project}' not found")
|
super().__init__(f"Version '{version}' for project '{project}' does not exist")
|
||||||
|
|
||||||
|
|
||||||
class NonexistentCategoryException(APIException):
|
class NonexistentCategoryException(APIException):
|
||||||
|
@ -22,12 +22,12 @@ class NonexistentCategoryException(APIException):
|
||||||
|
|
||||||
def __init__(self, project: str, version: str, category: str):
|
def __init__(self, project: str, version: str, category: str):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
f"Category '{category}' not found for project '{project}', version '{version}'"
|
f"Category '{category}' does not exist for project '{project}', version '{version}'"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class NoEntriesException(APIException):
|
class EmptyCategoryException(APIException):
|
||||||
status_code = status.HTTP_404_NOT_FOUND
|
status_code = status.HTTP_400_BAD_REQUEST
|
||||||
|
|
||||||
def __init__(self, project: str, version: str, category: str):
|
def __init__(self, project: str, version: str, category: str):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.2.1 on 2023-05-25 15:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("frog_api", "0010_alter_entry_category_alter_project_discord_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="entry",
|
||||||
|
name="description",
|
||||||
|
field=models.TextField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -73,6 +73,7 @@ class Entry(models.Model):
|
||||||
category = models.ForeignKey(Category, on_delete=models.CASCADE)
|
category = models.ForeignKey(Category, on_delete=models.CASCADE)
|
||||||
timestamp = models.IntegerField()
|
timestamp = models.IntegerField()
|
||||||
git_hash = models.CharField(max_length=40)
|
git_hash = models.CharField(max_length=40)
|
||||||
|
description = models.TextField(blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name_plural = "Entries"
|
verbose_name_plural = "Entries"
|
||||||
|
|
|
@ -42,4 +42,5 @@ class EntrySerializer(serializers.HyperlinkedModelSerializer):
|
||||||
"timestamp",
|
"timestamp",
|
||||||
"git_hash",
|
"git_hash",
|
||||||
"measures",
|
"measures",
|
||||||
|
"description",
|
||||||
]
|
]
|
||||||
|
|
|
@ -13,7 +13,13 @@ from frog_api.cache import (
|
||||||
invalidate_entries_cache,
|
invalidate_entries_cache,
|
||||||
set_entries_cache,
|
set_entries_cache,
|
||||||
)
|
)
|
||||||
from frog_api.exceptions import InvalidDataException, NoEntriesException
|
from frog_api.exceptions import (
|
||||||
|
InvalidDataException,
|
||||||
|
EmptyCategoryException,
|
||||||
|
NonexistentCategoryException,
|
||||||
|
NonexistentProjectException,
|
||||||
|
NonexistentVersionException,
|
||||||
|
)
|
||||||
from frog_api.models import Category, Entry, Measure, Project, Version
|
from frog_api.models import Category, Entry, Measure, Project, Version
|
||||||
from frog_api.serializers.model_serializers import EntrySerializer
|
from frog_api.serializers.model_serializers import EntrySerializer
|
||||||
from frog_api.serializers.request_serializers import CreateEntriesSerializer
|
from frog_api.serializers.request_serializers import CreateEntriesSerializer
|
||||||
|
@ -42,15 +48,6 @@ def get_latest_entry(
|
||||||
return EntrySerializer(entry).data
|
return EntrySerializer(entry).data
|
||||||
|
|
||||||
|
|
||||||
def get_latest_entry_throw(
|
|
||||||
project_slug: str, version_slug: str, category_slug: str
|
|
||||||
) -> EntryT:
|
|
||||||
entry = get_latest_entry(project_slug, version_slug, category_slug)
|
|
||||||
if entry is None:
|
|
||||||
raise NoEntriesException(project_slug, version_slug, category_slug)
|
|
||||||
return entry
|
|
||||||
|
|
||||||
|
|
||||||
def get_all_entries(
|
def get_all_entries(
|
||||||
project_slug: str, version_slug: str, category_slug: str
|
project_slug: str, version_slug: str, category_slug: str
|
||||||
) -> list[EntryT]:
|
) -> list[EntryT]:
|
||||||
|
@ -121,9 +118,10 @@ class ProjectDataView(APIView):
|
||||||
def get_progress_shield(
|
def get_progress_shield(
|
||||||
request: Request, project_slug: str, version_slug: str, category_slug: str
|
request: Request, project_slug: str, version_slug: str, category_slug: str
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
latest = get_latest_entry_throw(project_slug, version_slug, category_slug)
|
latest = get_latest_entry(project_slug, version_slug, category_slug)
|
||||||
|
|
||||||
assert latest is not None
|
if latest is None:
|
||||||
|
raise EmptyCategoryException(project_slug, version_slug, category_slug)
|
||||||
|
|
||||||
latest_measures = latest["measures"]
|
latest_measures = latest["measures"]
|
||||||
|
|
||||||
|
@ -191,11 +189,17 @@ class VersionDataView(APIView):
|
||||||
request_ser.is_valid(raise_exception=True)
|
request_ser.is_valid(raise_exception=True)
|
||||||
data = request_ser.data
|
data = request_ser.data
|
||||||
|
|
||||||
project = get_project(project_slug)
|
try:
|
||||||
|
project = get_project(project_slug)
|
||||||
|
except NonexistentProjectException:
|
||||||
|
raise InvalidDataException(f"Project '{project_slug}' does not exist")
|
||||||
|
|
||||||
validate_api_key(data["api_key"], project)
|
validate_api_key(data["api_key"], project)
|
||||||
|
|
||||||
version = get_version(version_slug, project)
|
try:
|
||||||
|
version = get_version(version_slug, project)
|
||||||
|
except NonexistentVersionException:
|
||||||
|
raise InvalidDataException(f"Version '{version_slug}' does not exist")
|
||||||
|
|
||||||
to_save: list[models.Model] = []
|
to_save: list[models.Model] = []
|
||||||
for entry in data["entries"]:
|
for entry in data["entries"]:
|
||||||
|
@ -203,7 +207,10 @@ class VersionDataView(APIView):
|
||||||
git_hash = entry["git_hash"]
|
git_hash = entry["git_hash"]
|
||||||
categories = entry["categories"]
|
categories = entry["categories"]
|
||||||
for cat in categories:
|
for cat in categories:
|
||||||
category = get_category(cat, version)
|
try:
|
||||||
|
category = get_category(cat, version)
|
||||||
|
except NonexistentCategoryException:
|
||||||
|
raise InvalidDataException(f"Category '{cat}' does not exist")
|
||||||
|
|
||||||
entry = Entry(category=category, timestamp=timestamp, git_hash=git_hash)
|
entry = Entry(category=category, timestamp=timestamp, git_hash=git_hash)
|
||||||
|
|
||||||
|
@ -300,9 +307,8 @@ class CategoryDataView(APIView):
|
||||||
|
|
||||||
match mode:
|
match mode:
|
||||||
case Mode.LATEST:
|
case Mode.LATEST:
|
||||||
entries = [
|
entry = get_latest_entry(project_slug, version_slug, category_slug)
|
||||||
get_latest_entry_throw(project_slug, version_slug, category_slug)
|
entries = [entry] if entry is not None else []
|
||||||
]
|
|
||||||
response_json = {project_slug: {version_slug: {category_slug: entries}}}
|
response_json = {project_slug: {version_slug: {category_slug: entries}}}
|
||||||
return Response(response_json)
|
return Response(response_json)
|
||||||
case Mode.ALL:
|
case Mode.ALL:
|
||||||
|
|
Loading…
Reference in New Issue