Skip to content

Commit bb52f89

Browse files
committed
added max spaces per user + added custom app name + fixed theming tests
1 parent 35eff63 commit bb52f89

File tree

7 files changed

+91
-21
lines changed

7 files changed

+91
-21
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 4.2.7 on 2024-01-14 23:06
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('cookbook', '0207_space_logo_color_128_space_logo_color_144_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='space',
15+
name='app_name',
16+
field=models.CharField(blank=True, max_length=40, null=True),
17+
),
18+
migrations.AddField(
19+
model_name='userpreference',
20+
name='max_owned_spaces',
21+
field=models.IntegerField(default=100),
22+
),
23+
]

cookbook/models.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from treebeard.mp_tree import MP_Node, MP_NodeManager
2525

2626
from recipes.settings import (COMMENT_PREF_DEFAULT, FRACTION_PREF_DEFAULT, KJ_PREF_DEFAULT,
27-
SORT_TREE_BY_NAME, STICKY_NAV_PREF_DEFAULT)
27+
SORT_TREE_BY_NAME, STICKY_NAV_PREF_DEFAULT, MAX_OWNED_SPACES_PREF_DEFAULT)
2828

2929

3030
def get_user_display_name(self):
@@ -288,7 +288,7 @@ class Space(ExportModelOperationsMixin('space'), models.Model):
288288
nav_logo = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_nav_logo')
289289
nav_bg_color = models.CharField(max_length=8, default='', blank=True, )
290290
nav_text_color = models.CharField(max_length=16, choices=NAV_TEXT_COLORS, default=BLANK)
291-
291+
app_name = models.CharField(max_length=40, null=True, blank=True, )
292292
logo_color_32 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_32')
293293
logo_color_128 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_128')
294294
logo_color_144 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_144')
@@ -409,7 +409,7 @@ class UserPreference(models.Model, PermissionModelMixin):
409409
nav_text_color = models.CharField(max_length=16, choices=NAV_TEXT_COLORS, default=DARK)
410410
nav_show_logo = models.BooleanField(default=True)
411411
nav_sticky = models.BooleanField(default=STICKY_NAV_PREF_DEFAULT)
412-
412+
max_owned_spaces = models.IntegerField(default=MAX_OWNED_SPACES_PREF_DEFAULT)
413413
default_unit = models.CharField(max_length=32, default='g')
414414
use_fractions = models.BooleanField(default=FRACTION_PREF_DEFAULT)
415415
use_kj = models.BooleanField(default=KJ_PREF_DEFAULT)
@@ -434,6 +434,15 @@ class UserPreference(models.Model, PermissionModelMixin):
434434
created_at = models.DateTimeField(auto_now_add=True)
435435
objects = ScopedManager(space='space')
436436

437+
def save(self, *args, **kwargs):
438+
if not self.pk:
439+
self.max_owned_spaces = MAX_OWNED_SPACES_PREF_DEFAULT
440+
self.comments = COMMENT_PREF_DEFAULT
441+
self.nav_sticky = STICKY_NAV_PREF_DEFAULT
442+
self.use_kj = KJ_PREF_DEFAULT
443+
self.use_fractions = FRACTION_PREF_DEFAULT
444+
445+
return super().save(*args, **kwargs)
437446
def __str__(self):
438447
return str(self.user)
439448

cookbook/templatetags/theming_tags.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def theme_values(request):
1515

1616
def get_theming_values(request):
1717
space = None
18-
if 'space' in request:
18+
if getattr(request,'space',None):
1919
space = request.space
2020
if not request.user.is_authenticated and UNAUTHENTICATED_THEME_FROM_SPACE > 0:
2121
with scopes_disabled():
@@ -46,16 +46,17 @@ def get_theming_values(request):
4646
'nav_bg_color': '#ddbf86',
4747
'nav_text_class': 'navbar-light',
4848
'sticky_nav': 'position: sticky; top: 0; left: 0; z-index: 1000;',
49+
'app_name': 'Tandoor Recipes',
4950
}
5051

51-
if request.user.is_authenticated:
52-
if request.user.userpreference.theme in themes:
53-
tv['theme'] = static(themes[ request.user.userpreference.theme])
54-
if request.user.userpreference.nav_bg_color:
55-
tv['nav_bg_color'] = request.user.userpreference.nav_bg_color
56-
if request.user.userpreference.nav_text_color and request.user.userpreference.nav_text_color in nav_text_type_mapping:
57-
tv['nav_text_class'] = nav_text_type_mapping[ request.user.userpreference.nav_text_color]
58-
if not request.user.userpreference.nav_sticky:
52+
if request.user.is_authenticated:
53+
if request.user.userpreference.theme in themes:
54+
tv['theme'] = static(themes[request.user.userpreference.theme])
55+
if request.user.userpreference.nav_bg_color:
56+
tv['nav_bg_color'] = request.user.userpreference.nav_bg_color
57+
if request.user.userpreference.nav_text_color and request.user.userpreference.nav_text_color in nav_text_type_mapping:
58+
tv['nav_text_class'] = nav_text_type_mapping[request.user.userpreference.nav_text_color]
59+
if not request.user.userpreference.nav_sticky:
5960
tv['sticky_nav'] = ''
6061

6162
if space:
@@ -73,4 +74,6 @@ def get_theming_values(request):
7374
tv['nav_bg_color'] = space.nav_bg_color
7475
if space.nav_text_color and space.nav_text_color in nav_text_type_mapping:
7576
tv['nav_text_class'] = nav_text_type_mapping[space.nav_text_color]
77+
if space.app_name:
78+
tv['app_name'] = space.app_name
7679
return tv

cookbook/tests/other/test_theming.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.contrib import auth
22
from django.templatetags.static import static
33
from django.test import RequestFactory
4+
from django_scopes import scopes_disabled
45

56
from cookbook.models import Space, UserPreference, UserFile
67
from cookbook.templatetags.theming_tags import theme_values, get_theming_values
@@ -20,32 +21,48 @@ def test_theming_function(space_1, u1_s1):
2021
assert get_theming_values(request)['nav_text_class'] == 'navbar-light'
2122
assert get_theming_values(request)['nav_logo'] == static('assets/brand_logo.png')
2223
assert get_theming_values(request)['sticky_nav'] == 'position: sticky; top: 0; left: 0; z-index: 1000;'
24+
assert get_theming_values(request)['app_name'] == 'Tandoor Recipes'
2325

24-
user.userpreference.theme = UserPreference.TANDOOR_DARK
25-
user.userpreference.nav_bg_color = '#ffffff'
26-
user.userpreference.nav_text_color = UserPreference.LIGHT
27-
user.userpreference.nav_sticky = False
28-
user.userpreference.save()
26+
with scopes_disabled():
27+
up = UserPreference.objects.filter(user=request.user).first()
28+
up.theme = UserPreference.TANDOOR_DARK
29+
up.nav_bg_color = '#ffffff'
30+
up.nav_text_color = UserPreference.LIGHT
31+
up.nav_sticky = False
32+
up.save()
33+
34+
request = RequestFactory()
35+
request.user = auth.get_user(u1_s1)
36+
request.space = space_1
2937

3038
# user values apply if only those are present
3139
assert get_theming_values(request)['theme'] == static('themes/tandoor_dark.min.css')
3240
assert get_theming_values(request)['nav_bg_color'] == '#ffffff'
3341
assert get_theming_values(request)['nav_text_class'] == 'navbar-dark'
3442
assert get_theming_values(request)['sticky_nav'] == ''
43+
assert get_theming_values(request)['app_name'] == 'Tandoor Recipes'
3544

3645
space_1.space_theme = Space.BOOTSTRAP
3746
space_1.nav_bg_color = '#000000'
3847
space_1.nav_text_color = UserPreference.DARK
48+
space_1.app_name = 'test_app_name'
3949
space_1.save()
4050

51+
request = RequestFactory()
52+
request.user = auth.get_user(u1_s1)
53+
request.space = space_1
54+
4155
# space settings apply when set
4256
assert get_theming_values(request)['theme'] == static('themes/bootstrap.min.css')
4357
assert get_theming_values(request)['nav_bg_color'] == '#000000'
4458
assert get_theming_values(request)['nav_text_class'] == 'navbar-light'
59+
assert get_theming_values(request)['app_name'] == 'test_app_name'
4560

4661
user.userspace_set.all().delete()
62+
request = RequestFactory()
63+
request.user = auth.get_user(u1_s1)
4764

4865
# default user settings should apply when user has no space
49-
assert get_theming_values(request)['nav_bg_color'] == '#ddbf86'
50-
assert get_theming_values(request)['nav_text_class'] == 'navbar-light'
66+
assert get_theming_values(request)['nav_bg_color'] == '#ffffff'
67+
assert get_theming_values(request)['nav_text_class'] == 'navbar-dark'
5168
assert get_theming_values(request)['nav_logo'] == static('assets/brand_logo.png')

cookbook/views/views.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ def space_overview(request):
7979
messages.add_message(request, messages.WARNING, _('This feature is not available in the demo version!'))
8080
else:
8181
if create_form.is_valid():
82+
if Space.objects.filter(created_by=request.user).count() >= request.user.userpreference.max_owned_spaces:
83+
messages.add_message(request, messages.ERROR,
84+
_('You have the reached the maximum amount of spaces that can be owned by you.') + f' ({request.user.userpreference.max_owned_spaces})')
85+
return HttpResponseRedirect(reverse('view_space_overview'))
86+
8287
created_space = Space.objects.create(
8388
name=create_form.cleaned_data['name'],
8489
created_by=request.user,
@@ -491,8 +496,8 @@ def web_manifest(request):
491496
]
492497

493498
manifest_info = {
494-
"name": "Tandoor Recipes",
495-
"short_name": "Tandoor",
499+
"name": theme_values['app_name'],
500+
"short_name": theme_values['app_name'],
496501
"description": _("Manage recipes, shopping list, meal plans and more."),
497502
"icons": icons,
498503
"start_url": "./search",

docs/system/configuration.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,18 @@ The default value for the user preference 'sticky navigation' (always show navba
524524
STICKY_NAV_PREF_DEFAULT=1
525525
```
526526

527+
#### Max owned spaces
528+
529+
> default `100` - options: `0-X`
530+
531+
The default for the number of spaces a user can own. By setting to 0 space creation for users will be disabled.
532+
Superusers can always bypass this limit.
533+
534+
```
535+
MAX_OWNED_SPACES_PREF_DEFAULT=100
536+
```
537+
538+
527539
### Cosmetic / Preferences
528540

529541
#### Timezone

recipes/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
FRACTION_PREF_DEFAULT = bool(int(os.getenv('FRACTION_PREF_DEFAULT', False)))
5858
KJ_PREF_DEFAULT = bool(int(os.getenv('KJ_PREF_DEFAULT', False)))
5959
STICKY_NAV_PREF_DEFAULT = bool(int(os.getenv('STICKY_NAV_PREF_DEFAULT', True)))
60+
MAX_OWNED_SPACES_PREF_DEFAULT = int(os.getenv('MAX_OWNED_SPACES_PREF_DEFAULT', 100))
6061
UNAUTHENTICATED_THEME_FROM_SPACE = int(os.getenv('UNAUTHENTICATED_THEME_FROM_SPACE', 0))
6162

6263
# minimum interval that users can set for automatic sync of shopping lists

0 commit comments

Comments
 (0)