Skip to content
Snippets Groups Projects
Commit ff4cd789 authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

wip - separated redmine issues, growing charts

parent c1994cfe
No related branches found
No related tags found
2 merge requests!787Release,!743Add Redmine datasets to charts, Instagram feed to homepage
Pipeline #12112 passed
...@@ -137,6 +137,9 @@ dmypy.json ...@@ -137,6 +137,9 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
# Requests-cache
redmine_cache.sqlite
##################################################### #####################################################
# CUSTOM # CUSTOM
......
...@@ -703,11 +703,13 @@ class ChartRedmineIssueDataset(blocks.StructBlock): ...@@ -703,11 +703,13 @@ class ChartRedmineIssueDataset(blocks.StructBlock):
required=False, required=False,
) )
created_on = blocks.CharBlock( created_on_min_date = blocks.DateBlock(
label="Filtr pro datum vytvoření", label="Min. datum vytvoření",
max_length=128, required=True
help_text="Např. >=2022-01-01, pro rozsah dat ><2022-01-01|2022-12-31. Více informací na pi2.cz/redmine-api", )
required=False, created_on_max_date = blocks.DateBlock(
label="Max. datum vytvoření",
required=True
) )
updated_on = blocks.CharBlock( updated_on = blocks.CharBlock(
label="Filtr pro datum aktualizace", label="Filtr pro datum aktualizace",
...@@ -722,23 +724,37 @@ class ChartRedmineIssueDataset(blocks.StructBlock): ...@@ -722,23 +724,37 @@ class ChartRedmineIssueDataset(blocks.StructBlock):
required=True, required=True,
) )
def _get_issues_url(self, value): split_per_project = blocks.BooleanBlock(
label="Rozdělit podle projektu",
required=False,
)
only_grow = blocks.BooleanBlock(
label="Pouze růst nahoru",
required=False,
)
def _get_issues_url(self, value, project_id):
url = "https://redmine.pirati.cz/issues.json" url = "https://redmine.pirati.cz/issues.json"
params = [ params = [
("sort", "created_on"), ("sort", "created_on"),
("limit", "100"), ("limit", "100"),
("created_on", f"><{value['created_on_min_date']}|{value['created_on_max_date']}"),
("project_id", project_id)
] ]
if "is_open" in value and "is_closed" in value: is_open = value.get("is_open", False)
is_closed = value.get("is_closed", False)
if is_open and is_closed:
params.append(("status_id", "*")) params.append(("status_id", "*"))
elif "is_open" in value: elif is_open:
params.append(("status_id", "open")) params.append(("status_id", "open"))
elif "is_closed" in value: elif is_closed:
params.append(("status_id", "closed")) params.append(("status_id", "closed"))
for string_filter in ("created_on", "updated_on"): if value.get("updated_on", "") != "":
if value.get(string_filter, "") != "": params.append(("updated_on", value["updated_on"]))
params.append((string_filter, value[string_filter]))
is_first = True is_first = True
...@@ -752,7 +768,7 @@ class ChartRedmineIssueDataset(blocks.StructBlock): ...@@ -752,7 +768,7 @@ class ChartRedmineIssueDataset(blocks.StructBlock):
return url return url
def _get_parsed_issues(self, value, issues_url) -> tuple: def _get_parsed_issues(self, value, labels, issues_url) -> tuple:
session = requests_cache.CachedSession( session = requests_cache.CachedSession(
"redmine_cache", "redmine_cache",
expire_after=datetime.timedelta(days=14), expire_after=datetime.timedelta(days=14),
...@@ -762,6 +778,8 @@ class ChartRedmineIssueDataset(blocks.StructBlock): ...@@ -762,6 +778,8 @@ class ChartRedmineIssueDataset(blocks.StructBlock):
issues_response.raise_for_status() issues_response.raise_for_status()
issues_response = issues_response.json() issues_response = issues_response.json()
only_grow = value.get("only_grow", False)
collected_issues = issues_response["issues"] collected_issues = issues_response["issues"]
offset = 0 offset = 0
...@@ -774,27 +792,22 @@ class ChartRedmineIssueDataset(blocks.StructBlock): ...@@ -774,27 +792,22 @@ class ChartRedmineIssueDataset(blocks.StructBlock):
collected_issues += issues_response["issues"] collected_issues += issues_response["issues"]
labels = []
for issue in collected_issues:
created_on_date = issue["created_on"].split("T")[0]
if created_on_date in labels:
continue
labels.append(created_on_date)
data = [0] * len(labels) data = [0] * len(labels)
current_issue_count = 0
current_label = labels[0]
ending_position = len(collected_issues) - 1 ending_position = len(collected_issues) - 1
current_issue_count = 0
current_label = datetime.date.fromisoformat(
collected_issues[0]["created_on"].split("T")[0]
)
if not only_grow:
for position, issue in enumerate( for position, issue in enumerate(
collected_issues collected_issues
): # Assume correct sorting order ): # Assume correct sorting order
created_on_date = issue["created_on"].split("T")[0] created_on_date = datetime.date.fromisoformat(
issue["created_on"].split("T")[0]
)
if current_label != created_on_date or position == ending_position: if current_label != created_on_date or position == ending_position:
data[ data[
...@@ -809,19 +822,85 @@ class ChartRedmineIssueDataset(blocks.StructBlock): ...@@ -809,19 +822,85 @@ class ChartRedmineIssueDataset(blocks.StructBlock):
break break
current_issue_count += 1 current_issue_count += 1
else:
issue_count_by_date = {}
for position, issue in enumerate(
collected_issues
): # Assume correct sorting order
created_on_date = datetime.date.fromisoformat(
issue["created_on"].split("T")[0]
)
if current_label not in issue_count_by_date:
issue_count_by_date[current_label] = 0
if current_label != created_on_date or position == ending_position:
issue_count_by_date[current_label] = current_issue_count # Assume labels are unique
current_label = created_on_date
if position == ending_position:
issue_count_by_date[current_label] = current_issue_count + 1
break
current_issue_count += 1
return labels, data print(issue_count_by_date)
previous_date = None
for date in labels:
if date not in issue_count_by_date:
if previous_date is None:
data.append(0)
continue
data.append(issue_count_by_date[previous_date])
continue
data.append(issue_count_by_date[date])
previous_date = date
return data
def get_context(self, value) -> list: def get_context(self, value) -> list:
context = super().get_context(value) context = super().get_context(value)
issues_url = self._get_issues_url(value) labels = []
context["parsed_issues"] = self._get_parsed_issues(value, issues_url)
for day_count in range(
(
value["created_on_max_date"]
- value["created_on_min_date"]
).days
+ 1
):
day = value["created_on_min_date"] + datetime.timedelta(days=day_count)
labels.append(day)
datasets = []
for project_id in value["projects"]:
issues_url = self._get_issues_url(value, project_id)
datasets.append({
"label": project_id,
"data": self._get_parsed_issues(value, labels, issues_url)
})
labels = [date.strftime("%d. %m. %Y") for date in labels]
context["parsed_issue_labels"] = labels
context["parsed_issues"] = datasets
return context return context
class Meta: class Meta:
label = "Zdroj dat z Redmine (úkoly)" label = "Zdroj dat z Redmine (úkoly vytvořené za den)"
help_text = (
"Po prvním otevření se bude stránka otevírat delší dobu, "
"zatímco se na pozadí načítají data do grafu. Poté bude "
"fungovat běžně."
)
class ChartBlock(blocks.StructBlock): class ChartBlock(blocks.StructBlock):
...@@ -843,6 +922,12 @@ class ChartBlock(blocks.StructBlock): ...@@ -843,6 +922,12 @@ class ChartBlock(blocks.StructBlock):
default="bar", default="bar",
) )
hide_points = blocks.BooleanBlock(
label="Schovat body",
required=False,
help_text="Pouze u linových grafů.",
)
local_labels = blocks.ListBlock( local_labels = blocks.ListBlock(
blocks.CharBlock( blocks.CharBlock(
max_length=40, max_length=40,
...@@ -881,8 +966,6 @@ class ChartBlock(blocks.StructBlock): ...@@ -881,8 +966,6 @@ class ChartBlock(blocks.StructBlock):
labels = value["local_labels"] labels = value["local_labels"]
for dataset in value["local_datasets"]: for dataset in value["local_datasets"]:
dataset = dict(dataset)
datasets.append( datasets.append(
{ {
"label": dataset["label"], "label": dataset["label"],
...@@ -891,13 +974,10 @@ class ChartBlock(blocks.StructBlock): ...@@ -891,13 +974,10 @@ class ChartBlock(blocks.StructBlock):
) )
elif len(value["redmine_issue_datasets"]) != 0: elif len(value["redmine_issue_datasets"]) != 0:
for dataset_wrapper in value["redmine_issue_datasets"]: for dataset_wrapper in value["redmine_issue_datasets"]:
single_label_set, data = ChartRedmineIssueDataset().get_context( redmine_context = ChartRedmineIssueDataset().get_context(dataset_wrapper)
dataset_wrapper
)["parsed_issues"]
labels += single_label_set
datasets = [{"label": dataset_wrapper["issue_label"], "data": data}] labels += redmine_context["parsed_issue_labels"]
datasets += redmine_context["parsed_issues"]
value["datasets"] = json.dumps(datasets) value["datasets"] = json.dumps(datasets)
value["labels"] = json.dumps([label for label in labels]) value["labels"] = json.dumps([label for label in labels])
......
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
tempDataset["borderColor"] = getColor(); tempDataset["borderColor"] = getColor();
tempDataset["borderWidth"] = 1; tempDataset["borderWidth"] = 1;
tempDataset["fill"] = true;
tempDataset["tension"] = 0.3;
finalDatasets.push(tempDataset); finalDatasets.push(tempDataset);
} }
...@@ -83,7 +85,13 @@ ...@@ -83,7 +85,13 @@
beginAtZero: true, beginAtZero: true,
}, },
}, },
}, }{% if value.hide_points %},
elements: {
point: {
radius: 0
}
}
{% endif %}
} }
} }
); );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment