diff options
| author | Hunternif | 2019-04-17 00:24:34 +0700 |
|---|---|---|
| committer | Hunternif | 2019-04-17 00:24:34 +0700 |
| commit | def305c11c9f3a8e0e347dab0b2ec03e7275c93c (patch) | |
| tree | 6f0f64dfd015186ef40843db54f07bfeafc9bc8e | |
| parent | 110c1125fe143ac91cbda007129ec84e5d21930d (diff) | |
Update metrics via tag API
| -rw-r--r-- | server/szurubooru/api/metric_api.py | 11 | ||||
| -rw-r--r-- | server/szurubooru/api/tag_api.py | 10 | ||||
| -rw-r--r-- | server/szurubooru/func/metrics.py | 25 | ||||
| -rw-r--r-- | server/szurubooru/rest/context.py | 26 |
4 files changed, 62 insertions, 10 deletions
diff --git a/server/szurubooru/api/metric_api.py b/server/szurubooru/api/metric_api.py index 82620a8..092d9e5 100644 --- a/server/szurubooru/api/metric_api.py +++ b/server/szurubooru/api/metric_api.py @@ -1,6 +1,6 @@ from typing import Optional, List, Dict from szurubooru import db, model, search, rest -from szurubooru.func import auth, metrics, snapshots, serialization, versions +from szurubooru.func import auth, metrics, snapshots, serialization, tags def _serialize(ctx: rest.Context, metric: model.Metric) -> rest.Response: @@ -12,11 +12,12 @@ def _serialize(ctx: rest.Context, metric: model.Metric) -> rest.Response: @rest.routes.post('/metrics/?') def create_tag(ctx: rest.Context, params: Dict[str, str] = {}) -> rest.Response: auth.verify_privilege(ctx.user, 'metrics:create') - tag_name = ctx.get_param_as_string_list('tag_name') - min = ctx.get_param_as_string_list('min', default=0.) - max = ctx.get_param_as_string_list('max', default=10.) + tag_name = ctx.get_param_as_string('tag_name') + tag = tags.get_tag_by_name(tag_name) + min = ctx.get_param_as_float('min', default=0.) + max = ctx.get_param_as_float('max', default=10.) - metric = metrics.create_metric(tag_name, min, max) + metric = metrics.create_metric(tag, min, max) ctx.session.add(metric) ctx.session.flush() snapshots.create(metric, ctx.user) diff --git a/server/szurubooru/api/tag_api.py b/server/szurubooru/api/tag_api.py index f9a15e7..71bcc99 100644 --- a/server/szurubooru/api/tag_api.py +++ b/server/szurubooru/api/tag_api.py @@ -1,7 +1,7 @@ from typing import Optional, List, Dict from datetime import datetime from szurubooru import db, model, search, rest -from szurubooru.func import auth, tags, snapshots, serialization, versions +from szurubooru.func import auth, tags, metrics, snapshots, serialization, versions _search_executor = search.Executor(search.configs.TagSearchConfig()) @@ -90,6 +90,14 @@ def update_tag(ctx: rest.Context, params: Dict[str, str]) -> rest.Response: implications = ctx.get_param_as_string_list('implications') _create_if_needed(implications, ctx.user) tags.update_tag_implications(tag, implications) + if ctx.has_param('metric'): + auth.verify_privilege(ctx.user, 'metrics:edit') + new_metric = metrics.update_metric(tag, ctx.get_param_as_list('metric')[0]) + if new_metric is not None: + auth.verify_privilege(ctx.user, 'metrics:create') + db.session.flush() + snapshots.create(new_metric, ctx.user) + tag.last_edit_time = datetime.utcnow() ctx.session.flush() snapshots.modify(tag, ctx.user) diff --git a/server/szurubooru/func/metrics.py b/server/szurubooru/func/metrics.py index 7b45b3d..bdf73ff 100644 --- a/server/szurubooru/func/metrics.py +++ b/server/szurubooru/func/metrics.py @@ -1,13 +1,17 @@ from typing import Any, Optional, Tuple, List, Dict, Callable import sqlalchemy as sa from szurubooru import config, db, model, errors, rest -from szurubooru.func import util, serialization, tags +from szurubooru.func import serialization class MetricAlreadyExistsError(errors.ValidationError): pass +class InvalidMetricError(errors.ValidationError): + pass + + class MetricSeralizer(serialization.BaseSerializer): def __init__(self, metric: model.Metric): self.metric = metric @@ -31,13 +35,26 @@ def serialize_metric(metric: model.Metric, options: List[str] = []) -> Optional[ return MetricSeralizer(metric).serialize(options) - def create_metric( - tag_name: str, + tag: model.Tag, min: float, max: float) -> model.Metric: - tag = tags.get_tag_by_name(tag_name) if tag.metric is not None: raise MetricAlreadyExistsError('Tag already has a metric.') metric = model.Metric(tag=tag, min=min, max=max) return metric + + +def update_metric(tag: model.Tag, metric_data) -> Optional[model.Metric]: + for field in ('min', 'max'): + if field not in metric_data: + raise InvalidMetricError('Metric is missing %r field.' % field) + + min, max = metric_data['min'], metric_data['max'] + if tag.metric is None: + tag.metric.min = min + tag.metric.max = max + return None + else: + metric = model.Metric(tag=tag, min=min, max=max) + return metric diff --git a/server/szurubooru/rest/context.py b/server/szurubooru/rest/context.py index 2aad101..647e2e3 100644 --- a/server/szurubooru/rest/context.py +++ b/server/szurubooru/rest/context.py @@ -160,6 +160,32 @@ class Context: raise errors.InvalidParameterError( 'Parameter %r must be an integer value.' % name) + def get_param_as_float( + self, + name: str, + default: Union[object, float] = MISSING, + min: Optional[float] = None, + max: Optional[float] = None) -> float: + if name not in self._params: + if default is not MISSING: + return cast(float, default) + raise errors.MissingRequiredParameterError( + 'Required parameter %r is missing.' % name) + value = self._params[name] + try: + value = float(value) + if min is not None and value < min: + raise errors.InvalidParameterError( + 'Parameter %r must be at least %r.' % (name, min)) + if max is not None and value > max: + raise errors.InvalidParameterError( + 'Parameter %r may not exceed %r.' % (name, max)) + return value + except (ValueError, TypeError): + pass + raise errors.InvalidParameterError( + 'Parameter %r must be a float value.' % name) + def get_param_as_bool( self, name: str, |