Skip to content

Commit 19e625a

Browse files
authored
0.2.0: Fixes and improvements (#33)
Fixes #27, #29, #13
1 parent b45cb75 commit 19e625a

File tree

12 files changed

+691
-621
lines changed

12 files changed

+691
-621
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ on:
55
- main
66
pull_request:
77
jobs:
8-
full_test_and_build:
9-
name: unit tests
8+
tests:
9+
name: tests
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v2
13-
- uses: actions/setup-python@v1
12+
- uses: actions/checkout@v3
13+
- uses: actions/setup-python@v4
1414
with:
15-
python-version: 3.9
15+
python-version: '3.10'
1616
- uses: snok/install-poetry@v1
1717
- run: poetry install
1818
- name: Run backend tests
@@ -22,10 +22,10 @@ jobs:
2222
name: mypy
2323
runs-on: ubuntu-latest
2424
steps:
25-
- uses: actions/checkout@v2
26-
- uses: actions/setup-python@v1
25+
- uses: actions/checkout@v3
26+
- uses: actions/setup-python@v4
2727
with:
28-
python-version: 3.9
28+
python-version: '3.10'
2929
- uses: snok/install-poetry@v1
3030
- run: |-
3131
poetry install
@@ -34,7 +34,11 @@ jobs:
3434
name: black
3535
runs-on: ubuntu-latest
3636
steps:
37-
- uses: actions/checkout@v2
38-
- uses: psf/black@stable
37+
- uses: actions/checkout@v3
38+
- uses: actions/setup-python@v4
3939
with:
40-
src: "."
40+
python-version: '3.10'
41+
- uses: snok/install-poetry@v1
42+
- run: |-
43+
poetry install
44+
poetry run black . --check

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Contributing
22

33
## Dependencies
4-
- Python >=3.9
4+
- Python >=3.10
55
- [Poetry](https://python-poetry.org/docs/master/#installing-with-the-official-installer)
66

77
## Setup

GUIDE.md

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Guide on how to monitor decomp progress using Frogress
1+
# Guide on how to monitor decomp progress using frogress
22

33
## Overview
44

5-
It will guide you to onboard your decomp project to Frogress.
5+
This guide will provide a flow for how to use frogress for your project.
66

77
```mermaid
88
sequenceDiagram
@@ -12,19 +12,19 @@ sequenceDiagram
1212
Contributor->>+CI: Trigger
1313
CI->>CI: Build
1414
CI->>CI: Calculate progress
15-
CI->>-Frogress: Upload progress
16-
Note over CI,Frogress: POST /data/project:/version:/
17-
Monitor->>Frogress: Fetch progress
18-
Note over Monitor,Frogress: GET /data/project:/version:/?mode=all
19-
Frogress->>Monitor: Return progress
15+
CI->>-frogress: Upload progress
16+
Note over CI,frogress: POST /data/project:/version:/
17+
Monitor->>frogress: Fetch progress
18+
Note over Monitor,frogress: GET /data/project:/version:/?mode=all
19+
frogress->>Monitor: Return progress
2020
Monitor->>Monitor: Render progress
2121
```
2222

2323
*CI: Continuous Integration services including GitHub Actions, Gitlab pipelines, Travis CI and Jenkins.*
2424

2525
## Steps
2626

27-
1. Contact Frogress admin to create project and assign api_key
27+
1. Contact frogress admin (Ethan) to add your project to the database and obtain an api_key
2828

2929
2. Create schema with `cli.py`
3030

@@ -45,9 +45,7 @@ sequenceDiagram
4545
./cli.py create version fireemblem8 us
4646
```
4747

48-
2.3 Create category (optional)
49-
50-
Default category: `default`
48+
2.3 Create category
5149

5250
```bash
5351
# Usage
@@ -56,14 +54,14 @@ sequenceDiagram
5654
./cli.py create category fireemblem8 us default
5755
```
5856

59-
3. Upload progress in CI
57+
3. Configure CI to upload data on build
6058

6159
3.1 API
6260

6361
```
6462
POST https://progress.deco.mp/data/project:/version:/
6563
```
66-
64+
6765
```python
6866
{
6967
"api_key": "",
@@ -80,39 +78,47 @@ sequenceDiagram
8078
```
8179

8280
3.2 Example
83-
81+
8482
https://github.com/FireEmblemUniverse/fireemblem8u/pull/307
8583

86-
4. Supplement historical data (optional)
84+
4. Supplement historical data (optional, one-time)
8785

88-
Calculate progress for historical commits and upload it to Frogress if you would like to draw historical curve.
86+
Calculate progress for historical commits and upload it to frogress for the purpose of visualizing and tracking historical data
8987

9088
[Example](https://github.com/laqieer/fireemblem8u/blob/master/.github/workflows/supplement-progress.yml)
9189

92-
5. Prune duplicated data (optional)
93-
94-
Background: https://github.com/decompals/frogress/issues/27
95-
96-
```
97-
# Usage
98-
./cli.py prune -h
99-
# Example
100-
./cli.py prune fireemblem8 us
101-
```
90+
5. Fetch project data
10291

103-
6. Fetch project data
92+
5.1 API
10493

105-
6.1 API
94+
There are 3 "modes" for returning results: `all`, `latest`, and `shield`. The first two are pretty self explanatory, and `shield` can be used to generate badges for your repo's README.md (shields.io).
10695
10796
```
10897
GET https://progress.deco.mp/data/project:/version:/?mode=all
10998
```
99+
```
100+
GET https://progress.deco.mp/data/project:/version:/?mode=latest
101+
```
102+
Note that the category and measure are required for mode `shield`.
103+
```
104+
GET https://progress.deco.mp/data/project:/version:/category:/?mode=shield&measure=MEASURE
105+
```
106+
107+
**Note:** Specifying a category in the request URL is optional for `all` and `latest` modes. If the category is not specified, results from all categories will be returned. However, for `shield`, it is necessary to specify the category and measure in the request url, as shown above.
108+
109+
`all` example:
110+
111+
`https://progress.deco.mp/data/fireemblem8/us/?mode=all`
112+
113+
`shield` example:
114+
115+
`https://progress.deco.mp/data/dukezh/us/default/?mode=shield&measure=bytes`
110116
111-
https://progress.deco.mp/data/fireemblem8/us/?mode=all
117+
5.2 Build a website
112118
113-
6.2 Build a website
119+
Build a website to display your progress!
114120
115-
Build a website to render progress graph using a library such as [uPlot](https://github.com/leeoniya/uPlot) and [Chart.js](https://www.chartjs.org).
121+
You can use the "latest" mode to retrieve just the latest datapoint or render full graphs using a library such as [uPlot](https://github.com/leeoniya/uPlot) or [Chart.js](https://www.chartjs.org)
116122
117123
- https://pikmin.dev
118124
- https://axiodl.com

cli.py

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -83,93 +83,6 @@ def delete_category(args: argparse.Namespace) -> None:
8383
print(response.text)
8484

8585

86-
def prune_entries(args: argparse.Namespace) -> None:
87-
# Get entries
88-
89-
url = f"{domain}/data/{args.project}/{args.version}?mode=all"
90-
91-
debug("GET " + url)
92-
93-
response = requests.get(url)
94-
print(response.text)
95-
96-
categories = response.json().get(args.project, {}).get(args.version, {})
97-
98-
if len(categories) == 0:
99-
return
100-
101-
# Filter entries
102-
103-
filtered = {}
104-
105-
for category, entries in categories.items():
106-
if len(entries) == 0:
107-
continue
108-
for entry in entries:
109-
if entry["git_hash"] not in filtered:
110-
filtered[entry["git_hash"]] = {
111-
"git_hash": entry["git_hash"],
112-
"timestamp": entry["timestamp"],
113-
"categories": {},
114-
}
115-
if category not in filtered[entry["git_hash"]]["categories"]:
116-
filtered[entry["git_hash"]]["categories"][category] = entry["measures"]
117-
else:
118-
for measure, value in entry["measures"].items():
119-
if (
120-
measure
121-
not in filtered[entry["git_hash"]]["categories"][category]
122-
):
123-
filtered[entry["git_hash"]]["categories"][category][
124-
measure
125-
] = value
126-
127-
entries = list(filtered.values())
128-
129-
# Clear entries
130-
131-
for category in categories.keys():
132-
# Delete categories
133-
134-
url = f"{domain}/projects/{args.project}/{args.version}/{category}/"
135-
136-
data = {"api_key": api_key}
137-
138-
debug("DELETE " + url)
139-
140-
response = requests.delete(url, json=data)
141-
print(response.text)
142-
143-
# Recreate categories
144-
145-
data["name"] = category
146-
147-
debug("POST " + url)
148-
149-
response = requests.post(url, json=data)
150-
print(response.text)
151-
152-
# Upload entries
153-
154-
url = f"{domain}/data/{args.project}/{args.version}/"
155-
156-
data = {"api_key": api_key, "entries": entries}
157-
158-
debug("POST " + url)
159-
160-
response = requests.post(url, json=data)
161-
print(response.status_code, response.text)
162-
163-
# Check entries
164-
165-
url = f"{domain}/data/{args.project}/{args.version}?mode=all"
166-
167-
debug("GET " + url)
168-
169-
response = requests.get(url)
170-
print(response.text)
171-
172-
17386
def main() -> None:
17487
parser = argparse.ArgumentParser()
17588

@@ -235,17 +148,6 @@ def main() -> None:
235148
delete_category_parser.add_argument("slug", help="the slug for the category")
236149
delete_category_parser.set_defaults(func=delete_category)
237150

238-
# Prune entries
239-
prune_parser = subparsers.add_parser(
240-
"prune",
241-
help="prune entries to remove duplicates",
242-
)
243-
prune_parser.add_argument(
244-
"project", help="the project for which to prune duplicated entries"
245-
)
246-
prune_parser.add_argument("version", help="the slug for the version")
247-
prune_parser.set_defaults(func=prune_entries)
248-
249151
args = parser.parse_args()
250152
args.func(args)
251153

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Generated by Django 4.2.1 on 2023-05-25 08:56
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
(
11+
"frog_api",
12+
"0001_squashed_0009_alter_project_discord_alter_project_repository_and_more",
13+
),
14+
]
15+
16+
operations = [
17+
migrations.AlterField(
18+
model_name="entry",
19+
name="category",
20+
field=models.ForeignKey(
21+
on_delete=django.db.models.deletion.CASCADE, to="frog_api.category"
22+
),
23+
),
24+
migrations.AlterField(
25+
model_name="project",
26+
name="discord",
27+
field=models.URLField(blank=True),
28+
),
29+
migrations.AlterField(
30+
model_name="project",
31+
name="repository",
32+
field=models.URLField(blank=True),
33+
),
34+
migrations.AlterField(
35+
model_name="project",
36+
name="website",
37+
field=models.URLField(blank=True),
38+
),
39+
migrations.AddConstraint(
40+
model_name="entry",
41+
constraint=models.UniqueConstraint(
42+
fields=("timestamp", "git_hash", "category"), name="unique entry"
43+
),
44+
),
45+
]

frog_api/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ class Entry(models.Model):
7777
class Meta:
7878
verbose_name_plural = "Entries"
7979
ordering = ["-timestamp"]
80+
constraints = [
81+
models.UniqueConstraint(
82+
fields=["timestamp", "git_hash", "category"], name="unique entry"
83+
)
84+
]
8085

8186
def __str__(self) -> str:
8287
time_string = datetime.utcfromtimestamp(self.timestamp).strftime(

0 commit comments

Comments
 (0)