From 7ba4c64a7449429b3aa430b81feab89efde26688 Mon Sep 17 00:00:00 2001 From: Ben Morse <35934884+Morsey187@users.noreply.github.com> Date: Fri, 7 May 2021 08:13:29 +0100 Subject: [PATCH 1/3] Feature/207 set file volume for an experiment (#261) * Add us file volume field * Add volume increment field and widget Co-authored-by: Ben Morse --- flare_portal/experiments/forms.py | 88 ++++++++++++++++++- .../0060_add_us_file_volume_fields.py | 24 +++++ ...61_instructionsmodule_volume_increments.py | 22 +++++ flare_portal/experiments/models/core.py | 4 + flare_portal/experiments/models/modules.py | 26 +++++- flare_portal/experiments/registry.py | 18 +++- .../experiments/experiment_form.html | 3 + flare_portal/experiments/tests/test_views.py | 2 + .../sass/components/_custom-array-widget.scss | 11 +++ flare_portal/static_src/sass/main.scss | 1 + .../templates/includes/form-group.html | 4 + .../templates/widgets/volume_increments.html | 12 +++ flare_portal/utils/validators.py | 9 ++ 13 files changed, 218 insertions(+), 6 deletions(-) create mode 100644 flare_portal/experiments/migrations/0060_add_us_file_volume_fields.py create mode 100644 flare_portal/experiments/migrations/0061_instructionsmodule_volume_increments.py create mode 100644 flare_portal/static_src/sass/components/_custom-array-widget.scss create mode 100644 flare_portal/templates/widgets/volume_increments.html create mode 100644 flare_portal/utils/validators.py diff --git a/flare_portal/experiments/forms.py b/flare_portal/experiments/forms.py index 102efc5a..340f41be 100644 --- a/flare_portal/experiments/forms.py +++ b/flare_portal/experiments/forms.py @@ -8,10 +8,19 @@ from django.core.validators import FileExtensionValidator from django.db.models import QuerySet from django.forms import inlineformset_factory +from django.utils.datastructures import MultiValueDict +from flare_portal.experiments.models.modules import get_volume_increments from flare_portal.users.models import User -from .models import BreakEndModule, BreakStartModule, Experiment, Participant, Project +from .models import ( + BreakEndModule, + BreakStartModule, + Experiment, + InstructionsModule, + Participant, + Project, +) class ExperimentForm(forms.ModelForm): @@ -20,8 +29,24 @@ class ExperimentForm(forms.ModelForm): max_value=1, min_value=0, widget=forms.NumberInput(attrs={"step": "0.01"}), - help_text="The minimum volume that you would like the participant to " - "abide by. Must be a value between 0 - 1, e.g. 0.5 equates to 50% volume.", + label="Minimum Device Volume", + help_text="Must be a value between 0 - 1, e.g. 0.5 equates to 50% volume. " + "The minimum volume that your participants must set their phones to during " + "the experiment. Setting this value lower than 1 gives participants the " + "option to reduce their device’s volume without interrupting the experiment.", + ) + us_file_volume = forms.FloatField( + required=True, + max_value=1, + min_value=0, + widget=forms.NumberInput(attrs={"step": "0.01"}), + label="US File Volume", + help_text="Must be a value between 0 - 1, e.g. 0.5 equates to 50% volume. Each " + ".wav file has a built-in volume setting, this is what will limit the true " + "volume a participant will hear. True volume equals file volume multiplied " + "by device volume. For example, if you set the file volume to .5 and the " + "participant’s device volume is set to 1, the true volume the participant " + "will hear is .5.", ) class Meta: @@ -36,6 +61,7 @@ class Meta: "rating_delay", "iti_min_delay", "iti_max_delay", + "us_file_volume", "minimum_volume", "rating_scale_anchor_label_left", "rating_scale_anchor_label_center", @@ -246,6 +272,62 @@ def save(self) -> None: self.participants.delete() +class VolumeIncrementsWidget(forms.MultiWidget): + """ + This is a Form Widget for use with a Postgres ArrayField. It implements + a multi-field interface to allow multiple float values to be submitted. + """ + + template_name = "widgets/volume_increments.html" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + self.default_values = kwargs.pop( + "default_values", [0.1, 0.2, 0.3, 0.9, 0.95, 1] + ) + widgets = [] + for _ in range(0, len(self.default_values)): + widgets.append(forms.NumberInput(attrs={"step": "0.01"})) + super().__init__(widgets, *args, **kwargs) + + def decompress(self, value: str) -> List[str]: + # Split combined value of the arrayfield into the values for each widget + if isinstance(value, str): + return list(value.split(",")) + return [ + None for _ in range(0, len(self.default_values)) + ] # return None for each widget + + def value_from_datadict(self, data: Any, files: Any, name: str) -> List[str]: + # Parse inputs by name and output array of values + if isinstance(data, MultiValueDict): + values = [] + for i in range(0, len(self.default_values)): + value = data.get(name + "_" + str(i), None) + if value: + values.append(value) + return values + return [] + + +class InstructionsModuleForm(forms.ModelForm): + class Meta: + model = InstructionsModule + fields = [ + "experiment", + "label", + "include_volume_calibration", + "volume_increments", + "end_screen_title", + "end_screen_body", + ] + widgets = { + "experiment": forms.HiddenInput(), + "volume_increments": VolumeIncrementsWidget( + default_values=get_volume_increments(), + ), + } + + class BreakStartModuleForm(forms.ModelForm): class Meta: model = BreakStartModule diff --git a/flare_portal/experiments/migrations/0060_add_us_file_volume_fields.py b/flare_portal/experiments/migrations/0060_add_us_file_volume_fields.py new file mode 100644 index 00000000..11a5b53c --- /dev/null +++ b/flare_portal/experiments/migrations/0060_add_us_file_volume_fields.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.6 on 2021-04-15 15:20 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('experiments', '0059_rename_task_to_trial'), + ] + + operations = [ + migrations.AddField( + model_name='experiment', + name='us_file_volume', + field=models.FloatField(default=1, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)]), + ), + migrations.AlterField( + model_name='instructionsmodule', + name='include_volume_calibration', + field=models.BooleanField(default=False, help_text='Enabling volume calibration will override the US file volume set in the experiment settings.'), + ), + ] diff --git a/flare_portal/experiments/migrations/0061_instructionsmodule_volume_increments.py b/flare_portal/experiments/migrations/0061_instructionsmodule_volume_increments.py new file mode 100644 index 00000000..92a82c52 --- /dev/null +++ b/flare_portal/experiments/migrations/0061_instructionsmodule_volume_increments.py @@ -0,0 +1,22 @@ +# Generated by Django 3.1.6 on 2021-04-16 12:04 + +import django.contrib.postgres.fields +import django.core.validators +from django.db import migrations, models +import flare_portal.experiments.models.modules +import flare_portal.utils.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('experiments', '0060_add_us_file_volume_fields'), + ] + + operations = [ + migrations.AddField( + model_name='instructionsmodule', + name='volume_increments', + field=django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)]), default=flare_portal.experiments.models.modules.get_volume_increments, size=6, validators=[flare_portal.utils.validators.validate_ascending_order]), + ), + ] diff --git a/flare_portal/experiments/models/core.py b/flare_portal/experiments/models/core.py index d8c046a2..274ee2e2 100644 --- a/flare_portal/experiments/models/core.py +++ b/flare_portal/experiments/models/core.py @@ -57,6 +57,10 @@ class Experiment(models.Model): project = models.ForeignKey("experiments.Project", on_delete=models.CASCADE) trial_length = models.FloatField() rating_delay = models.FloatField(default=1) + us_file_volume = models.FloatField( + default=1, + validators=[MinValueValidator(0), MaxValueValidator(1)], + ) minimum_volume = models.FloatField( default=1, validators=[MinValueValidator(0), MaxValueValidator(1)], diff --git a/flare_portal/experiments/models/modules.py b/flare_portal/experiments/models/modules.py index d16033bb..0961bbc3 100644 --- a/flare_portal/experiments/models/modules.py +++ b/flare_portal/experiments/models/modules.py @@ -2,7 +2,9 @@ from typing import Any, List from django import forms +from django.contrib.postgres.fields import ArrayField from django.core.exceptions import ValidationError +from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.template.defaultfilters import pluralize from django.utils.text import get_text_list @@ -11,6 +13,8 @@ from model_utils import Choices from model_utils.managers import InheritanceManager +from flare_portal.utils.validators import validate_ascending_order + from .. import constants from .core import Nameable @@ -365,8 +369,27 @@ class InstructionsScreenInline(InlineFormSetFactory): factory_kwargs = {"extra": 0} +def get_volume_increments() -> List[float]: + return [0.5, 0.65, 0.8, 0.9, 0.95, 1] + + class InstructionsModule(Module): - include_volume_calibration = models.BooleanField(default=False) + include_volume_calibration = models.BooleanField( + default=False, + help_text=( + "Enabling volume calibration will override the US file " + "volume set in the experiment settings." + ), + ) + volume_increments = ArrayField( + models.FloatField( + blank=False, + validators=[MinValueValidator(0), MaxValueValidator(1)], + ), + size=6, + default=get_volume_increments, + validators=[validate_ascending_order], + ) end_screen_title = models.CharField(max_length=255, blank=True) end_screen_body = models.TextField( blank=True, @@ -384,6 +407,7 @@ def get_module_config(self) -> constants.ModuleConfigType: type=self.get_module_tag(), config={ "include_volume_calibration": self.include_volume_calibration, + "volume_increments": self.volume_increments, "end_screen_title": self.end_screen_title, "end_screen_body": self.end_screen_body, "screens": [ diff --git a/flare_portal/experiments/registry.py b/flare_portal/experiments/registry.py index 9f82b98b..0d0c4003 100644 --- a/flare_portal/experiments/registry.py +++ b/flare_portal/experiments/registry.py @@ -15,7 +15,7 @@ UpdateWithInlinesView, ) -from .forms import BreakStartModuleForm +from .forms import BreakStartModuleForm, InstructionsModuleForm from .models import ( AffectiveRatingData, AffectiveRatingModule, @@ -251,6 +251,16 @@ class BreakModuleCreateView(ModuleCreateView): form_class = BreakStartModuleForm +class InstructionsModuleUpdateView(ModuleUpdateView): + model = InstructionsModule + form_class = InstructionsModuleForm + + +class InstructionsModuleCreateView(ModuleCreateView): + model = InstructionsModule + form_class = InstructionsModuleForm + + module_registry = ModuleRegistry() module_registry.register(AffectiveRatingModule) @@ -261,7 +271,11 @@ class BreakModuleCreateView(ModuleCreateView): module_registry.register(CriterionModule) module_registry.register(ContingencyAwarenessModule) module_registry.register(FearConditioningModule) -module_registry.register(InstructionsModule) +module_registry.register( + InstructionsModule, + update_view_class=InstructionsModuleUpdateView, + create_view_class=InstructionsModuleCreateView, +) module_registry.register(TaskInstructionsModule) module_registry.register(TextModule) module_registry.register(WebModule) diff --git a/flare_portal/experiments/templates/experiments/experiment_form.html b/flare_portal/experiments/templates/experiments/experiment_form.html index 5b25e744..6c01c5c9 100644 --- a/flare_portal/experiments/templates/experiments/experiment_form.html +++ b/flare_portal/experiments/templates/experiments/experiment_form.html @@ -89,6 +89,9 @@

Assets

{% include "includes/form-group.html" with field=form.us accept="audio/wav,audio/mp3" %}
+
+ {% include "includes/form-group.html" with field=form.us_file_volume %} +
{% include "includes/form-group.html" with field=form.minimum_volume %}
diff --git a/flare_portal/experiments/tests/test_views.py b/flare_portal/experiments/tests/test_views.py index 803896cd..1f55d77f 100644 --- a/flare_portal/experiments/tests/test_views.py +++ b/flare_portal/experiments/tests/test_views.py @@ -402,6 +402,7 @@ def test_create_experiment(self) -> None: "iti_min_delay": "1", "iti_max_delay": "3", "minimum_volume": "1", + "us_file_volume": "0.5", "rating_scale_anchor_label_left": "Certain no beep", "rating_scale_anchor_label_center": "Uncertain", "rating_scale_anchor_label_right": "Certain beep", @@ -541,6 +542,7 @@ def test_update_experiment(self) -> None: "iti_min_delay": "1", "iti_max_delay": "3", "minimum_volume": "1", + "us_file_volume": "0.5", "rating_scale_anchor_label_left": "Certain no beep", "rating_scale_anchor_label_center": "Uncertain", "rating_scale_anchor_label_right": "Certain beep", diff --git a/flare_portal/static_src/sass/components/_custom-array-widget.scss b/flare_portal/static_src/sass/components/_custom-array-widget.scss new file mode 100644 index 00000000..260e8ec3 --- /dev/null +++ b/flare_portal/static_src/sass/components/_custom-array-widget.scss @@ -0,0 +1,11 @@ +.custom-array-widget { + display: flex; + + &__input-wrapper { + margin-right: 6px; + + &:last-child { + margin-right: 0; + } + } +} diff --git a/flare_portal/static_src/sass/main.scss b/flare_portal/static_src/sass/main.scss index 2ab097cf..cc6efef4 100755 --- a/flare_portal/static_src/sass/main.scss +++ b/flare_portal/static_src/sass/main.scss @@ -3,4 +3,5 @@ @import 'vendor/tabler'; @import 'components/custom-checkbox-group'; +@import 'components/custom-array-widget'; @import 'components/custom-file'; diff --git a/flare_portal/templates/includes/form-group.html b/flare_portal/templates/includes/form-group.html index 728be0bf..50be4bf6 100644 --- a/flare_portal/templates/includes/form-group.html +++ b/flare_portal/templates/includes/form-group.html @@ -48,6 +48,10 @@ {% endif %}
+ {% elif field|widget_type == 'volumeincrementswidget' %} +
+ {{ field|add_class:"form-control"|add_error_class:"is-invalid" }} +
{% else %} {{ field|add_class:"form-control"|add_error_class:"is-invalid" }} {% endif %} diff --git a/flare_portal/templates/widgets/volume_increments.html b/flare_portal/templates/widgets/volume_increments.html new file mode 100644 index 00000000..94df32d0 --- /dev/null +++ b/flare_portal/templates/widgets/volume_increments.html @@ -0,0 +1,12 @@ +{% spaceless %} +
+ {% for widget in widget.subwidgets %} +
+ + {% include widget.template_name %} +
+ {% endfor %} +
+{% endspaceless %} diff --git a/flare_portal/utils/validators.py b/flare_portal/utils/validators.py new file mode 100644 index 00000000..f1e6a4d6 --- /dev/null +++ b/flare_portal/utils/validators.py @@ -0,0 +1,9 @@ +from typing import List + +from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ + + +def validate_ascending_order(values: List[float]) -> None: + if not all(values[i] <= values[i + 1] for i in range(len(values) - 1)): + raise ValidationError(_("Values must be in ascending order")) From b9ee93ecb2c86aa38252b888b177c8115fc40634 Mon Sep 17 00:00:00 2001 From: Ben Morse <35934884+Morsey187@users.noreply.github.com> Date: Wed, 2 Jun 2021 19:37:29 +0100 Subject: [PATCH 2/3] Create LICENSE (#321) --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..a236670f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 flare-kcl + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From b3e57888d8694e938a8fe52b0f9940c10e131c5e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 27 Jul 2021 07:41:05 +0000 Subject: [PATCH 3/3] Bump faker from 8.1.2 to 8.10.3 Bumps [faker](https://github.com/joke2k/faker) from 8.1.2 to 8.10.3. - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v8.1.2...v8.10.3) Signed-off-by: dependabot-preview[bot] --- poetry.lock | 31 ++++++++++++++++--------------- pyproject.toml | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/poetry.lock b/poetry.lock index e611e8a8..ac4acd3f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -57,7 +57,7 @@ cffi = ">=1.1" six = ">=1.4.1" [package.extras] -tests = ["pytest (>=3.2.1,<3.3.0 || >3.3.0)"] +tests = ["pytest (>=3.2.1,!=3.3.0)"] typecheck = ["mypy"] [[package]] @@ -188,11 +188,11 @@ cffi = ">=1.12" six = ">=1.4.1" [package.extras] -docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0,<3.1.0 || >3.1.0,<3.1.1 || >3.1.1)", "sphinx-rtd-theme"] +docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"] +test = ["pytest (>=3.6.0,!=3.9.0,!=3.9.1,!=3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] [[package]] name = "decorator" @@ -263,7 +263,7 @@ python-versions = ">=3.4" Django = ">=1.8,<4" [package.extras] -lint = ["isort (4.3.21)", "flake8 (3.8.3)", "black (19.10b0)"] +lint = ["isort (==4.3.21)", "flake8 (==3.8.3)", "black (==19.10b0)"] [[package]] name = "django-csp" @@ -278,7 +278,7 @@ Django = ">=1.8" [package.extras] jinja2 = ["jinja2 (>=2.9.6)"] -tests = ["pytest (<4.0)", "pytest-django", "pytest-flakes (1.0.1)", "pytest-pep8 (1.0.6)", "pep8 (1.4.6)", "mock (1.0.1)", "six (1.12.0)", "jinja2 (>=2.9.6)"] +tests = ["pytest (<4.0)", "pytest-django", "pytest-flakes (==1.0.1)", "pytest-pep8 (==1.0.6)", "pep8 (==1.4.6)", "mock (==1.0.1)", "six (==1.12.0)", "jinja2 (>=2.9.6)"] [[package]] name = "django-extensions" @@ -428,7 +428,7 @@ doc = ["sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"] [[package]] name = "faker" -version = "8.1.2" +version = "8.10.3" description = "Faker is a Python package that generates fake data for you." category = "main" optional = false @@ -540,6 +540,7 @@ python-versions = ">=2.7" [package.dependencies] ipython = {version = ">=7.17.0", markers = "python_version > \"3.6\""} +toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} [[package]] name = "ipython" @@ -605,7 +606,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" parso = ">=0.7.0,<0.8.0" [package.extras] -qa = ["flake8 (3.7.9)"] +qa = ["flake8 (==3.7.9)"] testing = ["Django (<3.1)", "colorama", "docopt", "pytest (>=3.9.0,<5.0.0)"] [[package]] @@ -949,7 +950,7 @@ six = "*" [package.extras] docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] -tests = ["pytest (>=3.2.1,<3.3.0 || >3.3.0)", "hypothesis (>=3.27.0)"] +tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] [[package]] name = "pyopenssl" @@ -1029,7 +1030,7 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] [[package]] name = "s3transfer" @@ -1155,8 +1156,8 @@ intervals = ["intervals (>=0.7.1)"] ipaddress = ["ipaddr"] password = ["passlib (>=1.6,<2.0)"] phone = ["phonenumbers (>=5.9.2)"] -test = ["pytest (>=2.7.1)", "Pygments (>=1.2)", "Jinja2 (>=2.3)", "docutils (>=0.10)", "flexmock (>=0.9.7)", "mock (2.0.0)", "psycopg2 (>=2.5.1)", "pytz (>=2014.2)", "python-dateutil (>=2.2)", "pymysql", "flake8 (>=2.4.0)", "isort (>=4.2.2)"] -test_all = ["anyjson (>=0.3.3)", "arrow (>=0.3.4)", "Babel (>=1.3)", "colour (>=0.0.4)", "cryptography (>=0.6)", "enum34", "intervals (>=0.7.1)", "ipaddr", "passlib (>=1.6,<2.0)", "phonenumbers (>=5.9.2)", "pytest (>=2.7.1)", "Pygments (>=1.2)", "Jinja2 (>=2.3)", "docutils (>=0.10)", "flexmock (>=0.9.7)", "mock (2.0.0)", "psycopg2 (>=2.5.1)", "pytz (>=2014.2)", "python-dateutil (>=2.2)", "pymysql", "flake8 (>=2.4.0)", "isort (>=4.2.2)", "python-dateutil", "furl (>=0.4.1)"] +test = ["pytest (>=2.7.1)", "Pygments (>=1.2)", "Jinja2 (>=2.3)", "docutils (>=0.10)", "flexmock (>=0.9.7)", "mock (==2.0.0)", "psycopg2 (>=2.5.1)", "pytz (>=2014.2)", "python-dateutil (>=2.2)", "pymysql", "flake8 (>=2.4.0)", "isort (>=4.2.2)"] +test_all = ["anyjson (>=0.3.3)", "arrow (>=0.3.4)", "Babel (>=1.3)", "colour (>=0.0.4)", "cryptography (>=0.6)", "enum34", "intervals (>=0.7.1)", "ipaddr", "passlib (>=1.6,<2.0)", "phonenumbers (>=5.9.2)", "pytest (>=2.7.1)", "Pygments (>=1.2)", "Jinja2 (>=2.3)", "docutils (>=0.10)", "flexmock (>=0.9.7)", "mock (==2.0.0)", "psycopg2 (>=2.5.1)", "pytz (>=2014.2)", "python-dateutil (>=2.2)", "pymysql", "flake8 (>=2.4.0)", "isort (>=4.2.2)", "python-dateutil", "furl (>=0.4.1)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -1255,7 +1256,7 @@ pyOpenSSL = {version = ">=0.14", optional = true, markers = "extra == \"secure\" [package.extras] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] brotli = ["brotlipy (>=0.6.0)"] [[package]] @@ -1321,7 +1322,7 @@ gunicorn = ["gunicorn"] [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "ddfb1511bb0f2d71739fa5d29511384e5af89c954a5f6d0e16822d76ed35c3b7" +content-hash = "8cc0433cf12f9d522a1660de0037cebb4ad3d87edbcae2be2eef97f6364d1115" [metadata.files] appdirs = [ @@ -1521,8 +1522,8 @@ factory-boy = [ {file = "factory_boy-3.2.0.tar.gz", hash = "sha256:401cc00ff339a022f84d64a4339503d1689e8263a4478d876e58a3295b155c5b"}, ] faker = [ - {file = "Faker-8.1.2-py3-none-any.whl", hash = "sha256:156854f36d4086bb21ff85a79b4d6a6403a240cd2c17a33a44b8ea4ff4e957c2"}, - {file = "Faker-8.1.2.tar.gz", hash = "sha256:a2ed065342e91a7672407325848cd5728d5e5eb4928d0a1c478fd4f0dd97d1f7"}, + {file = "Faker-8.10.3-py3-none-any.whl", hash = "sha256:f27a2a5c34042752f9d5fea2a9667aed5265d7d7bdd5ce83bc03b2f8a540d148"}, + {file = "Faker-8.10.3.tar.gz", hash = "sha256:771b21ab55924867ac865f4b0c2f547c200172293b1056be16289584ef1215cb"}, ] filelock = [ {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, diff --git a/pyproject.toml b/pyproject.toml index 01549581..f77071ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ django-extra-views = "^0.13.0" django-solo = "^1.1.5" Pillow = "^8.1.1" Markdown = "3.1.1" -Faker = "^8.1.2" +Faker = "^8.10.3" [tool.poetry.extras] gunicorn = ["gunicorn"]