Merge branch 'feature/keywords-rework' into feature/fulltext-search

# Conflicts:
#	cookbook/admin.py
#	cookbook/helper/recipe_search.py
#	cookbook/models.py
#	cookbook/static/vue/js/import_response_view.js
#	cookbook/static/vue/js/offline_view.js
#	cookbook/static/vue/js/recipe_search_view.js
#	cookbook/static/vue/js/recipe_view.js
#	cookbook/static/vue/js/supermarket_view.js
#	cookbook/templates/sw.js
#	cookbook/views/api.py
#	cookbook/views/views.py
#	vue/src/locales/en.json
#	vue/webpack-stats.json
#	vue/yarn.lock
This commit is contained in:
vabene1111
2021-06-30 15:06:03 +02:00
183 changed files with 32502 additions and 13884 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2 on 2021-04-22 21:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0123_invitelink_email'),
]
operations = [
migrations.AlterField(
model_name='userpreference',
name='search_style',
field=models.CharField(choices=[('SMALL', 'Small'), ('LARGE', 'Large'), ('NEW', 'New')], default='LARGE', max_length=64),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 3.2.3 on 2021-05-30 15:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0123_invitelink_email'),
]
operations = [
migrations.AlterField(
model_name='userpreference',
name='theme',
field=models.CharField(choices=[('BOOTSTRAP', 'Bootstrap'), ('DARKLY', 'Darkly'), ('FLATLY', 'Flatly'), ('SUPERHERO', 'Superhero'), ('TANDOOR', 'Tandoor')], default='FLATLY', max_length=128),
),
]

View File

@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0124_alter_userpreference_theme'),
('cookbook', '0124_alter_userpreference_search_style'),
]
operations = [

View File

@@ -0,0 +1,17 @@
# Generated by Django 3.2.3 on 2021-06-07 14:21
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0126_alter_userpreference_theme'),
]
operations = [
migrations.RemoveField(
model_name='invitelink',
name='username',
),
]

View File

@@ -0,0 +1,30 @@
# Generated by Django 3.2.3 on 2021-06-08 10:23
import cookbook.models
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0127_remove_invitelink_username'),
]
operations = [
migrations.CreateModel(
name='UserFile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
('file', models.FileField(upload_to='files/')),
('file_size_kb', models.IntegerField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(models.Model, cookbook.models.PermissionModelMixin),
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 3.2.3 on 2021-06-08 10:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0128_userfile'),
]
operations = [
migrations.RemoveField(
model_name='space',
name='allow_files',
),
migrations.AddField(
model_name='space',
name='max_file_storage_mb',
field=models.IntegerField(default=0, help_text='Maximum file storage for space in MB. 0 for unlimited, -1 to disable file upload.'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.3 on 2021-06-08 10:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0129_auto_20210608_1233'),
]
operations = [
migrations.AlterField(
model_name='userfile',
name='file_size_kb',
field=models.IntegerField(blank=True, default=0),
),
]

View File

@@ -0,0 +1,24 @@
# Generated by Django 3.2.4 on 2021-06-08 17:29
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0130_alter_userfile_file_size_kb'),
]
operations = [
migrations.AddField(
model_name='step',
name='file',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='cookbook.userfile'),
),
migrations.AlterField(
model_name='step',
name='type',
field=models.CharField(choices=[('TEXT', 'Text'), ('TIME', 'Time'), ('FILE', 'File')], default='TEXT', max_length=16),
),
]

View File

@@ -0,0 +1,111 @@
# Generated by Django 3.1.7 on 2021-04-07 20:00
import annoying.fields
from django.conf import settings
from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import SearchVectorField, SearchVector
from django.db import migrations, models
from django.db.models import deletion
from django_scopes import scopes_disabled
from django.utils import translation
from cookbook.managers import DICTIONARY
from cookbook.models import Recipe, Step, Index, PermissionModelMixin, nameSearchField, allSearchFields
def set_default_search_vector(apps, schema_editor):
if settings.DATABASES['default']['ENGINE'] not in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
return
language = DICTIONARY.get(translation.get_language(), 'simple')
with scopes_disabled():
# TODO this approach doesn't work terribly well if multiple languages are in use
# I'm also uncertain about forcing unaccent here
Recipe.objects.all().update(
name_search_vector=SearchVector('name__unaccent', weight='A', config=language),
desc_search_vector=SearchVector('description__unaccent', weight='B', config=language)
)
Step.objects.all().update(search_vector=SearchVector('instruction__unaccent', weight='B'))
class Migration(migrations.Migration):
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('cookbook', '0131_auto_20210608_1929'),
]
operations = [
migrations.AddField(
model_name='recipe',
name='desc_search_vector',
field=SearchVectorField(null=True),
),
migrations.AddField(
model_name='recipe',
name='name_search_vector',
field=SearchVectorField(null=True),
),
migrations.AddIndex(
model_name='recipe',
index=GinIndex(fields=['name_search_vector', 'desc_search_vector'], name='cookbook_re_name_se_bdf3ca_gin'),
),
migrations.AddField(
model_name='step',
name='search_vector',
field=SearchVectorField(null=True),
),
migrations.AddIndex(
model_name='step',
index=GinIndex(fields=['search_vector'], name='cookbook_st_search__2ef7fa_gin'),
),
migrations.AddIndex(
model_name='cooklog',
index=Index(fields=['id', 'recipe', '-created_at', 'rating'], name='cookbook_co_id_37485a_idx'),
),
migrations.AddIndex(
model_name='food',
index=Index(fields=['id', 'name'], name='cookbook_fo_id_22b733_idx'),
),
migrations.AddIndex(
model_name='ingredient',
index=Index(fields=['id', 'food', 'unit'], name='cookbook_in_id_3368be_idx'),
),
migrations.AddIndex(
model_name='keyword',
index=Index(fields=['id', 'name'], name='cookbook_ke_id_ebc03f_idx'),
),
migrations.AddIndex(
model_name='recipe',
index=Index(fields=['id', 'name', 'description'], name='cookbook_re_id_e4c2d4_idx'),
),
migrations.AddIndex(
model_name='recipebook',
index=Index(fields=['name', 'description'], name='cookbook_re_name_bbe446_idx'),
),
migrations.AddIndex(
model_name='viewlog',
index=Index(fields=['recipe', '-created_at'], name='cookbook_vi_recipe__5cd178_idx'),
),
migrations.CreateModel(
name='SearchFields',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True)),
('field', models.CharField(max_length=64, unique=True)),
],
bases=(models.Model, PermissionModelMixin),
),
migrations.CreateModel(
name='SearchPreference',
fields=[
('user', annoying.fields.AutoOneToOneField(on_delete=deletion.CASCADE, primary_key=True, serialize=False, to='auth.user')),
('search', models.CharField(choices=[('plain', 'Simple'), ('phrase', 'Phrase'), ('websearch', 'Web'), ('raw', 'Raw')], default='plain', max_length=32)),
('lookup', models.BooleanField(default=False)),
('fulltext', models.ManyToManyField(blank=True, related_name='fulltext_fields', to='cookbook.SearchFields')),
('icontains', models.ManyToManyField(blank=True, default=nameSearchField, related_name='icontains_fields', to='cookbook.SearchFields')),
('istartswith', models.ManyToManyField(blank=True, related_name='istartswith_fields', to='cookbook.SearchFields')),
('trigram', models.ManyToManyField(blank=True, related_name='trigram_fields', to='cookbook.SearchFields')),
('unaccent', models.ManyToManyField(blank=True, default=allSearchFields, related_name='unaccent_fields', to='cookbook.SearchFields')),
],
bases=(models.Model, PermissionModelMixin),
),
migrations.RunPython(
set_default_search_vector
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.4 on 2021-06-12 18:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0131_auto_20210608_1929'),
]
operations = [
migrations.AddField(
model_name='sharelink',
name='request_count',
field=models.IntegerField(default=0),
),
]

View File

@@ -0,0 +1,23 @@
from cookbook.models import SearchFields
from django.db import migrations
def create_searchfields(apps, schema_editor):
SearchFields.objects.create(name='Name', field='name')
SearchFields.objects.create(name='Description', field='description')
SearchFields.objects.create(name='Instructions', field='steps__instruction')
SearchFields.objects.create(name='Ingredients', field='steps__ingredients__food__name')
SearchFields.objects.create(name='Keywords', field='keywords__name')
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0132_build_full_text_index'),
]
operations = [
migrations.RunPython(
create_searchfields
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.4 on 2021-06-12 18:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0132_sharelink_request_count'),
]
operations = [
migrations.AddField(
model_name='sharelink',
name='abuse_blocked',
field=models.BooleanField(default=False),
),
]

View File

@@ -0,0 +1,70 @@
# Generated by Django 3.1.7 on 2021-03-30 19:42
from treebeard.mp_tree import MP_Node
from django.db import migrations, models
from django_scopes import scopes_disabled
# update if needed
steplen = MP_Node.steplen
alphabet = MP_Node.alphabet
node_order_by = ["name"]
def update_paths(apps, schema_editor):
with scopes_disabled():
Node = apps.get_model("cookbook", "Keyword")
nodes = Node.objects.all().order_by(*node_order_by)
for i, node in enumerate(nodes, 1):
# for default values, this resolves to: "{:04d}".format(i)
node.path = f"{{:{alphabet[0]}{steplen}d}}".format(i)
if nodes:
Node.objects.bulk_update(nodes, ["path"])
def backwards(apps, schema_editor):
"""nothing to do"""
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0133_create_searchfields'),
]
operations = [
migrations.AddField(
model_name='keyword',
name='depth',
field=models.PositiveIntegerField(default=1),
preserve_default=False,
),
migrations.AddField(
model_name='keyword',
name='numchild',
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name='keyword',
name='path',
field=models.CharField(default="", max_length=255, unique=False),
preserve_default=False,
),
migrations.AlterField(
model_name='userpreference',
name='use_fractions',
field=models.BooleanField(default=True),
),
migrations.RunPython(update_paths, backwards),
migrations.AlterField(
model_name="keyword",
name="path",
field=models.CharField(max_length=255, unique=True),
),
migrations.AlterUniqueTogether(
name='keyword',
unique_together=set(),
),
migrations.AddConstraint(
model_name='keyword',
constraint=models.UniqueConstraint(fields=('space', 'name'), name='unique_name_per_space'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.4 on 2021-06-15 19:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0133_sharelink_abuse_blocked'),
]
operations = [
migrations.AddField(
model_name='space',
name='allow_sharing',
field=models.BooleanField(default=True),
),
]

View File

@@ -0,0 +1,29 @@
# Generated by Django 3.2.4 on 2021-06-15 20:10
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0134_space_allow_sharing'),
]
operations = [
migrations.AddField(
model_name='ingredient',
name='space',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'),
),
migrations.AddField(
model_name='nutritioninformation',
name='space',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'),
),
migrations.AddField(
model_name='step',
name='space',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.2.4 on 2021-06-17 11:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0135_auto_20210615_2210'),
]
operations = [
migrations.AddField(
model_name='importlog',
name='imported_recipes',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='importlog',
name='total_recipes',
field=models.IntegerField(default=0),
),
]

View File

@@ -0,0 +1,34 @@
# Generated by Django 3.2.4 on 2021-06-17 13:01
from django.db import migrations
from django.db.models import Subquery, OuterRef
from django_scopes import scopes_disabled
from django.db import migrations, models
import django.db.models.deletion
def migrate_spaces(apps, schema_editor):
with scopes_disabled():
Recipe = apps.get_model('cookbook', 'Recipe')
Step = apps.get_model('cookbook', 'Step')
Ingredient = apps.get_model('cookbook', 'Ingredient')
NutritionInformation = apps.get_model('cookbook', 'NutritionInformation')
Step.objects.filter(recipe__isnull=True).delete()
Ingredient.objects.filter(step__recipe__isnull=True).delete()
NutritionInformation.objects.filter(recipe__isnull=True).delete()
Step.objects.update(space=Subquery(Step.objects.filter(pk=OuterRef('pk')).values('recipe__space')[:1]))
Ingredient.objects.update(space=Subquery(Ingredient.objects.filter(pk=OuterRef('pk')).values('step__recipe__space')[:1]))
NutritionInformation.objects.update(space=Subquery(NutritionInformation.objects.filter(pk=OuterRef('pk')).values('recipe__space')[:1]))
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0136_auto_20210617_1343'),
]
operations = [
migrations.RunPython(migrate_spaces),
]

View File

@@ -0,0 +1,31 @@
# Generated by Django 3.2.4 on 2021-06-17 14:02
from django.db import migrations
from django.db.models import Subquery, OuterRef
from django_scopes import scopes_disabled
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0137_auto_20210617_1501'),
]
operations = [
migrations.AlterField(
model_name='ingredient',
name='space',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'),
),
migrations.AlterField(
model_name='nutritioninformation',
name='space',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'),
),
migrations.AlterField(
model_name='step',
name='space',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'),
),
]

View File

@@ -0,0 +1,20 @@
# Generated by Django 3.2.4 on 2021-06-22 16:14
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0138_auto_20210617_1602'),
]
operations = [
migrations.AddField(
model_name='space',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
]

View File

@@ -0,0 +1,20 @@
# Generated by Django 3.2.4 on 2021-06-22 16:19
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0139_space_created_at'),
]
operations = [
migrations.AddField(
model_name='userpreference',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
]