Compare commits
14 Commits
7e978dd657
...
595e0a47b9
Author | SHA1 | Date |
---|---|---|
Luca | 595e0a47b9 | |
Luca | 36d75dc50d | |
Luca | 71fc7ed07e | |
Luca | 468f68c2cb | |
Luca | 3e75b76ac9 | |
Luca | adbb5685a0 | |
Luca | 818e478353 | |
Luca | 0dd2c8f31a | |
Luca | 59644b7b4b | |
Luca | 54296ebcf7 | |
Luca | cfbc4ef61c | |
Luca | fdc74bbf9e | |
Luca | 5ac11e16e8 | |
Luca | c3f2c0bcfa |
|
@ -1,10 +1,15 @@
|
|||
**/__pycache__
|
||||
*.bkp
|
||||
.dockerignore
|
||||
.drone.yml
|
||||
.editorconfig
|
||||
.git*
|
||||
.idea
|
||||
Dockerfile
|
||||
Dockerfile-dev
|
||||
README.md
|
||||
db.sqlite3
|
||||
docker-compose.yml
|
||||
env
|
||||
setup.cfg
|
||||
storage
|
||||
|
|
16
.drone.yml
16
.drone.yml
|
@ -4,10 +4,15 @@ kind: pipeline
|
|||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: yes
|
||||
|
||||
steps:
|
||||
- name: check style
|
||||
image: python:3.12-alpine
|
||||
commands:
|
||||
- apk add --no-cache git # required by isort to skip files in .gitignore
|
||||
- pip install black isort
|
||||
- black --check .
|
||||
- isort -c .
|
||||
|
||||
- name: deploy staging
|
||||
image: ghcr.io/appleboy/drone-ssh
|
||||
environment:
|
||||
|
@ -26,6 +31,8 @@ steps:
|
|||
when:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
|
||||
- name: deploy production
|
||||
image: ghcr.io/appleboy/drone-ssh
|
||||
|
@ -35,7 +42,10 @@ steps:
|
|||
when:
|
||||
branch:
|
||||
- live
|
||||
event:
|
||||
- push
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
root = true
|
||||
|
||||
[*.html]
|
||||
indent_size = 4
|
||||
indent_style = space
|
|
@ -158,3 +158,6 @@ cython_debug/
|
|||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# E.g. copies of old dev database
|
||||
*.bkp
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
FROM python:3.10-alpine3.17
|
||||
|
||||
RUN apk add --no-cache git
|
||||
FROM python:3.12-alpine3.19
|
||||
|
||||
RUN adduser -h /opt/shiftregister -D shiftregister
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
FROM python:3.10-alpine3.17
|
||||
|
||||
RUN apk add --no-cache git
|
||||
FROM python:3.12-alpine3.19
|
||||
|
||||
RUN adduser -h /home/shiftregister -D shiftregister
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# shiftregister
|
||||
|
||||
![kontakt logo with its left half rotated 180 degrees, resembling the left shift operator](assets/tonkakt.svg)
|
||||
![kontakt logo with its left half rotated 180 degrees, resembling the left shift operator](shiftregister/core/static/tonkakt.svg)
|
||||
|
||||
## [CI Mirror](https://git.luj0ga.de/kontakt/shiftregister) / [Drone CI](https://ci.luj0ga.de/kontakt/shiftregister)
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
amqp==5.1.1
|
||||
asgiref==3.5.0
|
||||
asgiref==3.8.1
|
||||
async-timeout==4.0.2
|
||||
beautifulsoup4==4.12.2
|
||||
billiard==3.6.4.0
|
||||
celery==5.2.6
|
||||
beautifulsoup4==4.12.3
|
||||
billiard==4.2.0
|
||||
celery==5.4.0
|
||||
certifi==2021.10.8
|
||||
charset-normalizer==2.0.12
|
||||
click==8.1.2
|
||||
|
@ -11,31 +11,31 @@ click-didyoumean==0.3.0
|
|||
click-plugins==1.1.1
|
||||
click-repl==0.2.0
|
||||
Deprecated==1.2.13
|
||||
Django==4.0.4
|
||||
django-dynamic-preferences==1.15.0
|
||||
django-phonenumber-field==6.1.0
|
||||
icalendar==4.0.9
|
||||
Django==5.0.4
|
||||
django-dynamic-preferences==1.16.0
|
||||
django-phonenumber-field==7.3.0
|
||||
icalendar==5.0.12
|
||||
idna==3.3
|
||||
kombu==5.2.4
|
||||
librabbitmq==2.0.0
|
||||
kombu==5.3.7
|
||||
packaging==21.3
|
||||
persisting-theory==1.0
|
||||
phonenumbers==8.12.47
|
||||
prompt-toolkit==3.0.29
|
||||
psycopg2-binary==2.9.3
|
||||
psycopg2-binary==2.9.9
|
||||
pyparsing==3.0.8
|
||||
pypng==0.20220715.0
|
||||
python-dateutil==2.8.2
|
||||
pytz==2022.1
|
||||
qrcode==7.4.2
|
||||
redis==4.2.2
|
||||
requests==2.27.1
|
||||
sentry-sdk==1.5.10
|
||||
redis==5.0.4
|
||||
requests==2.31.0
|
||||
sentry-sdk==2.0.1
|
||||
six==1.16.0
|
||||
soupsieve==2.4.1
|
||||
sqlparse==0.4.2
|
||||
typing_extensions==4.5.0
|
||||
urllib3==1.26.9
|
||||
vine==5.0.0
|
||||
typing_extensions==4.11.0
|
||||
tzdata==2024.1
|
||||
urllib3==2.2.1
|
||||
vine==5.1.0
|
||||
wcwidth==0.2.5
|
||||
wrapt==1.14.0
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[isort]
|
||||
line_length=88
|
||||
profile=black
|
||||
skip_gitignore=True
|
|
@ -1,7 +1,7 @@
|
|||
from django.contrib import admin
|
||||
from django.contrib.admin import DateFieldListFilter
|
||||
|
||||
from .models import Room, Shift, Helper, ShiftRegistration, Message, LoginToken
|
||||
from .models import Helper, LoginToken, Message, Room, Shift, ShiftRegistration
|
||||
|
||||
|
||||
@admin.register(Room)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.conf import settings
|
||||
|
||||
from .models import LoginToken
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from dynamic_preferences.registries import global_preferences_registry
|
||||
from dynamic_preferences import types
|
||||
import phonenumbers
|
||||
import datetime
|
||||
|
||||
import phonenumbers
|
||||
from dynamic_preferences import types
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
|
||||
helper = types.Section("helper")
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
from django import forms
|
||||
from .models import Helper
|
||||
from phonenumber_field.formfields import PhoneNumberField
|
||||
from phonenumber_field.validators import validate_international_phonenumber
|
||||
from django.core.exceptions import ValidationError
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
from phonenumber_field.formfields import PhoneNumberField
|
||||
from phonenumber_field.validators import validate_international_phonenumber
|
||||
|
||||
from .models import Helper
|
||||
|
||||
global_preferences = global_preferences_registry.manager()
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# Generated by Django 4.0.4 on 2022-04-27 14:11
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import phonenumber_field.modelfields
|
||||
from django.db import migrations, models
|
||||
|
||||
import shiftregister.app.models
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
from django.db import models
|
||||
import secrets
|
||||
from django.shortcuts import reverse
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Case, Count, ExpressionWrapper, F, Q, When
|
||||
from django.shortcuts import reverse
|
||||
from django.template import Context, Template
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from django.utils import timezone
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
global_preferences = global_preferences_registry.manager()
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@ from django.db.models.signals import pre_save
|
|||
from django.dispatch import receiver
|
||||
from django.shortcuts import reverse
|
||||
from django.template import Context, Template
|
||||
|
||||
from shiftregister.core.signals import populate_nav
|
||||
|
||||
from .models import Message, Shift
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import timezone
|
||||
from django.conf import settings
|
||||
import requests
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
|
||||
BASE_URL = "https://api.sipgate.com/v2"
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import requests
|
||||
from django.conf import settings
|
||||
from phonenumber_field.phonenumber import PhoneNumber
|
||||
import requests
|
||||
|
||||
|
||||
BASE_URL = "https://api.sipgate.com/v2"
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import sentry_sdk
|
||||
from celery import shared_task
|
||||
from .models import Message, ShiftRegistration
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
|
||||
from .models import Message, ShiftRegistration
|
||||
from .sipgate.sms import send as send_sms
|
||||
import sentry_sdk
|
||||
|
||||
global_preferences = global_preferences_registry.manager()
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from .models import Shift, LoginToken, Helper, ShiftRegistration
|
||||
from django.db import transaction
|
||||
from django.db.models import F, Count, Q, ExpressionWrapper
|
||||
from django.core.cache import cache
|
||||
from .forms import RegisterForm, EmptyForm, AstaForm
|
||||
from django.db.models.fields import DateTimeField
|
||||
import datetime
|
||||
import math
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
import datetime
|
||||
from .decorators import event_state
|
||||
from django.core.cache import cache
|
||||
from django.db import transaction
|
||||
from django.db.models import Count, ExpressionWrapper, F, Q
|
||||
from django.db.models.fields import DateTimeField
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils import timezone
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
import math
|
||||
|
||||
from .decorators import event_state
|
||||
from .forms import AstaForm, EmptyForm, RegisterForm
|
||||
from .models import Helper, LoginToken, Shift, ShiftRegistration
|
||||
|
||||
global_preferences = global_preferences_registry.manager()
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .signals import populate_nav
|
||||
from .signals import populate_footer_nav, populate_nav
|
||||
|
||||
|
||||
def nav(request):
|
||||
|
@ -9,6 +9,15 @@ def nav(request):
|
|||
for item in items
|
||||
]
|
||||
|
||||
return {
|
||||
"nav_items": nav_items,
|
||||
}
|
||||
return {"nav_items": nav_items}
|
||||
|
||||
|
||||
def footer_nav(request):
|
||||
nav_items = [
|
||||
item
|
||||
for _, items in populate_footer_nav.send(sender=request)
|
||||
if isinstance(items, list)
|
||||
for item in items
|
||||
]
|
||||
|
||||
return {"footer_nav_items": nav_items}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from django.dispatch import Signal
|
||||
|
||||
populate_nav = Signal()
|
||||
|
||||
populate_footer_nav = Signal()
|
||||
|
|
Before Width: | Height: | Size: 903 B After Width: | Height: | Size: 903 B |
|
@ -110,9 +110,13 @@
|
|||
{% endblock %}
|
||||
<div class="breadcrumb has-dot-separator is-flex-grow-1 is-right ml-5">
|
||||
<ul>
|
||||
<li><a href="{% url 'pages:view' 'map' %}">Karte</a></li>
|
||||
<li><a href="{% url 'pages:view' 'faq' %}">Häufig gestellte Fragen</a></li>
|
||||
<li><a href="{% url 'pages:view' 'about' %}">Über diese Seite/Impressum</a></li>
|
||||
{% for item in footer_nav_items %}
|
||||
<li>
|
||||
<{% if item.link %}a{% else %}p{% endif %}{% if item.class %} class="{{ item.class }}"{% endif %}{% if item.link %} href="{{ item.link }}"{% endif %}>
|
||||
{{ item.text }}
|
||||
</{% if item.link %}a{% else %}p{% endif %}>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.contrib import admin
|
||||
from django.shortcuts import reverse
|
||||
|
||||
from .models import *
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Django 4.0.4 on 2023-05-07 16:00
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Generated by Django 4.0.4 on 2023-05-13 17:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
import shiftregister.fallback.models
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
from shiftregister.importer.models import *
|
||||
from django.db.models import Max, Sum
|
||||
from django.db.models import Count, Exists, OuterRef, ExpressionWrapper
|
||||
from django.db.models.lookups import LessThan
|
||||
from django.db.models.fields import DateTimeField
|
||||
from base64 import urlsafe_b64encode
|
||||
import math
|
||||
import secrets
|
||||
from base64 import urlsafe_b64encode
|
||||
|
||||
from django.db.models import Count, Exists, ExpressionWrapper, Max, OuterRef, Sum
|
||||
from django.db.models.fields import DateTimeField
|
||||
from django.db.models.lookups import LessThan
|
||||
|
||||
from shiftregister.importer.models import *
|
||||
|
||||
night_shift_query = Q(start_at__hour__gte=21) | Q(start_at__hour__lte=10)
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
from datetime import datetime
|
||||
|
||||
from celery import shared_task
|
||||
from .models import FallbackAssignment
|
||||
from shiftregister.app.models import ShiftRegistration
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from django.db.models import Case, Count, ExpressionWrapper, F, Q, When
|
||||
from django.utils import timezone
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
|
||||
from datetime import datetime
|
||||
from django.utils import timezone
|
||||
|
||||
from shiftregister.app.models import ShiftRegistration
|
||||
|
||||
from .models import FallbackAssignment
|
||||
|
||||
global_preferences = global_preferences_registry.manager()
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from base64 import urlsafe_b64decode
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.db.models import Count
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
|
||||
from shiftregister.fallback.models import TeamMember
|
||||
|
||||
# Create your views here.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from .models import Feedback
|
||||
from django.forms import ModelForm
|
||||
from django import forms
|
||||
from django.forms import ModelForm
|
||||
|
||||
from .models import Feedback
|
||||
|
||||
|
||||
class FeedbackForm(ModelForm):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Django 4.0.4 on 2023-05-25 14:16
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# Generated by Django 4.0.4 on 2023-05-27 17:48
|
||||
|
||||
from django.db import migrations, models
|
||||
import secrets
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from django.db import models
|
||||
from secrets import token_urlsafe
|
||||
|
||||
from django.db import models
|
||||
|
||||
from shiftregister.app.models import Helper
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django.dispatch import receiver
|
||||
from django.shortcuts import reverse
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
|
||||
from shiftregister.core.signals import populate_nav
|
||||
|
||||
global_preferences = global_preferences_registry.manager()
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
from django.shortcuts import render, get_object_or_404
|
||||
from .forms import FeedbackForm
|
||||
from .models import Feedback, ShareToken
|
||||
from shiftregister.app.models import LoginToken
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
|
||||
from shiftregister.app.models import LoginToken
|
||||
|
||||
from .forms import FeedbackForm
|
||||
from .models import Feedback, ShareToken
|
||||
|
||||
|
||||
def feedback(request, token):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from .models import Calendar
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
from datetime import timezone
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from icalendar import Calendar
|
||||
|
||||
from .models import Event, Room, Shift
|
||||
import requests
|
||||
|
||||
|
||||
def import_calendar(calendar):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Django 4.0.4 on 2022-04-27 14:11
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.db import models
|
||||
|
||||
from shiftregister.app.models import *
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from celery import shared_task
|
||||
|
||||
from .importer import import_calendar
|
||||
from .models import Calendar
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from django.db import models
|
||||
from django.db.models import Count, Case, F, When, Sum
|
||||
from django.db.models import Case, Count, F, Sum, When
|
||||
from django.http import HttpResponse
|
||||
from shiftregister.app.models import Helper, Room, Shift, ShiftRegistration, Message
|
||||
|
||||
from shiftregister.app.models import Helper, Message, Room, Shift, ShiftRegistration
|
||||
from shiftregister.fallback.models import FallbackAssignment
|
||||
from shiftregister.importer.models import Event
|
||||
|
||||
|
@ -159,9 +160,11 @@ def metrics(request):
|
|||
),
|
||||
(
|
||||
"worked_seconds_total",
|
||||
worked_seconds_total.total_seconds()
|
||||
if worked_seconds_total
|
||||
else 0.0,
|
||||
(
|
||||
worked_seconds_total.total_seconds()
|
||||
if worked_seconds_total
|
||||
else 0.0
|
||||
),
|
||||
),
|
||||
(
|
||||
"worked_shifts_total",
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from django.contrib import admin
|
||||
from .models import Page
|
||||
from pathlib import Path
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Page
|
||||
|
||||
|
||||
def reimport(modeladmin, request, queryset):
|
||||
for page in queryset:
|
||||
|
@ -13,6 +15,21 @@ def reimport(modeladmin, request, queryset):
|
|||
|
||||
@admin.register(Page)
|
||||
class PageAdmin(admin.ModelAdmin):
|
||||
fields = ("url", "content", "title", "visible", "kind")
|
||||
list_display = ("url", "title", "visible", "kind")
|
||||
fields = (
|
||||
"url",
|
||||
"content",
|
||||
"title",
|
||||
"visible",
|
||||
"kind",
|
||||
"show_in_footer_nav",
|
||||
"show_in_main_nav",
|
||||
)
|
||||
list_display = (
|
||||
"url",
|
||||
"title",
|
||||
"visible",
|
||||
"kind",
|
||||
"show_in_footer_nav",
|
||||
"show_in_main_nav",
|
||||
)
|
||||
actions = (reimport,)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from django.apps import AppConfig
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class PagesConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "shiftregister.pages"
|
||||
|
||||
def ready(self):
|
||||
from . import signals
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from pathlib import Path
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from ...models import Page
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 5.0.4 on 2024-05-03 21:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pages", "0002_page_kind_alter_page_title"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="page",
|
||||
name="show_in_footer_nav",
|
||||
field=models.BooleanField(default=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="page",
|
||||
name="show_in_main_nav",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
|
@ -16,6 +16,8 @@ class Page(models.Model):
|
|||
visible = models.BooleanField(default=True)
|
||||
title = models.CharField(blank=True, max_length=200)
|
||||
kind = models.CharField(choices=KIND_CHOICES, default=REGULAR, max_length=8)
|
||||
show_in_footer_nav = models.BooleanField(default=True)
|
||||
show_in_main_nav = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
from django.dispatch import receiver
|
||||
from django.urls import reverse
|
||||
|
||||
from shiftregister.core.signals import populate_footer_nav, populate_nav
|
||||
|
||||
from .models import Page
|
||||
|
||||
|
||||
@receiver(populate_footer_nav, dispatch_uid="populate_pages_footer_nav")
|
||||
def populate_pages_footer_nav(sender, **kwargs):
|
||||
return [
|
||||
{
|
||||
"link": reverse("pages:view", args=(page.url,)),
|
||||
"text": page.title or page.url,
|
||||
}
|
||||
for page in Page.objects.filter(visible=True)
|
||||
if page.visible and page.show_in_footer_nav
|
||||
]
|
||||
|
||||
|
||||
@receiver(populate_nav, dispatch_uid="populate_pages_nav")
|
||||
def populate_pages_nav(sender, **kwargs):
|
||||
return [
|
||||
{
|
||||
"link": reverse("pages:view", args=(page.url,)),
|
||||
"text": page.title or page.url,
|
||||
}
|
||||
for page in Page.objects.filter(visible=True)
|
||||
if page.visible and page.show_in_main_nav
|
||||
]
|
|
@ -1,8 +1,9 @@
|
|||
from django.views.generic import DetailView
|
||||
from django.shortcuts import redirect
|
||||
from django.core.validators import URLValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import URLValidator
|
||||
from django.http import HttpResponseNotFound
|
||||
from django.shortcuts import redirect
|
||||
from django.views.generic import DetailView
|
||||
|
||||
from .models import Page
|
||||
|
||||
# Create your views here.
|
||||
|
|
|
@ -10,12 +10,13 @@ For the full list of settings and their values, see
|
|||
https://docs.djangoproject.com/en/4.0/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
|
||||
import sentry_sdk
|
||||
from django.contrib.messages import constants as messages
|
||||
from sentry_sdk.integrations.celery import CeleryIntegration
|
||||
from sentry_sdk.integrations.django import DjangoIntegration
|
||||
from django.contrib.messages import constants as messages
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
@ -39,15 +40,15 @@ ALLOWED_HOSTS = list(filter(lambda s: s != "", getenv("ALLOWED_HOSTS", "").split
|
|||
|
||||
INSTALLED_APPS = [
|
||||
"dynamic_preferences",
|
||||
"shiftregister.app.apps.AppConfig",
|
||||
"shiftregister.core.apps.CoreConfig",
|
||||
"shiftregister.fallback.apps.FallbackConfig",
|
||||
"shiftregister.importer.apps.ImporterConfig",
|
||||
"shiftregister.metrics.apps.MetricsConfig",
|
||||
"shiftregister.pages.apps.PagesConfig",
|
||||
"shiftregister.signage.apps.SignageConfig",
|
||||
"shiftregister.team.apps.TeamConfig",
|
||||
"shiftregister.feedback.apps.FeedbackConfig",
|
||||
"shiftregister.app",
|
||||
"shiftregister.core",
|
||||
"shiftregister.fallback",
|
||||
"shiftregister.importer",
|
||||
"shiftregister.metrics",
|
||||
"shiftregister.pages",
|
||||
"shiftregister.signage",
|
||||
"shiftregister.team",
|
||||
"shiftregister.feedback",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
|
@ -85,6 +86,7 @@ TEMPLATES = [
|
|||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
"shiftregister.app.context_processors.proc",
|
||||
"shiftregister.core.context_processors.footer_nav",
|
||||
"shiftregister.core.context_processors.nav",
|
||||
],
|
||||
},
|
||||
|
@ -146,10 +148,6 @@ USE_TZ = True
|
|||
STATIC_ROOT = "/opt/shiftregister/static"
|
||||
STATIC_URL = "static/"
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / "assets",
|
||||
]
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
||||
|
||||
|
@ -178,7 +176,7 @@ CELERY_BEAT_SCHEDULE = {
|
|||
},
|
||||
"deactivate-fallbacks-every-300-seconds": {
|
||||
"task": "shiftregister.fallback.tasks.deactivate_fallbacks",
|
||||
"schedule": float(getenv("FALLBACK_DEACTIVAtE_INTERVAL", 300.0)), # seconds
|
||||
"schedule": float(getenv("FALLBACK_DEACTIVATE_INTERVAL", 300.0)), # seconds
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-18 13:10
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
from shiftregister.app.models import *
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from datetime import timedelta
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Case, Count, F, ExpressionWrapper, Q, Sum, When
|
||||
from django.db.models import Case, Count, ExpressionWrapper, F, Q, Sum, When
|
||||
from django.shortcuts import render
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import Helper, Shift, ShiftRegistration
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from .models import IncomingMessage, RoomViewToken
|
||||
|
||||
# Register your models here.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django import forms
|
||||
from .models import ShiftRegistration, Helper
|
||||
|
||||
from .models import Helper, ShiftRegistration
|
||||
|
||||
|
||||
# placeholder form for simple submit button use cases so we get csrf protection
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Django 4.0.4 on 2023-05-06 23:27
|
||||
|
||||
from django.db import migrations, models
|
||||
import phonenumber_field.modelfields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# Generated by Django 4.0.4 on 2023-05-18 15:15
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
import shiftregister.team.models
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import secrets
|
||||
|
||||
from django.db import models
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
from shiftregister.app.models import *
|
||||
import secrets
|
||||
|
||||
# Create your models here.
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from django.dispatch import receiver
|
||||
from django.shortcuts import reverse
|
||||
from dynamic_preferences.registries import global_preferences_registry
|
||||
|
||||
from shiftregister.core.signals import populate_nav
|
||||
|
||||
from .models import IncomingMessage
|
||||
|
||||
global_preferences = global_preferences_registry.manager()
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import sentry_sdk
|
||||
from celery import shared_task
|
||||
from django.conf import settings
|
||||
|
||||
from shiftregister.app.sipgate.history import list_incoming_sms
|
||||
|
||||
from .models import IncomingMessage
|
||||
import sentry_sdk
|
||||
|
||||
|
||||
@shared_task
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django import template
|
||||
from re import ASCII, sub
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils import timezone
|
||||
from django.db.models.fields import DateTimeField
|
||||
from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
|
||||
from .models import (
|
||||
ShiftRegistration,
|
||||
Room,
|
||||
Shift,
|
||||
Helper,
|
||||
Message,
|
||||
IncomingMessage,
|
||||
RoomViewToken,
|
||||
)
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.views.generic.edit import FormMixin
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib import messages
|
||||
from django.db import models, transaction
|
||||
from django.core.paginator import Paginator
|
||||
from .forms import BulkMessage, HelperShift, HelperMessage
|
||||
from datetime import timedelta
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.core.paginator import Paginator
|
||||
from django.db import models, transaction
|
||||
from django.db.models import Case, Count, ExpressionWrapper, F, Q, When
|
||||
from django.db.models.fields import DateTimeField
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils import timezone
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.views.generic.edit import FormMixin
|
||||
|
||||
from .forms import BulkMessage, HelperMessage, HelperShift
|
||||
from .models import (
|
||||
Helper,
|
||||
IncomingMessage,
|
||||
Message,
|
||||
Room,
|
||||
RoomViewToken,
|
||||
Shift,
|
||||
ShiftRegistration,
|
||||
)
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ Including another URLconf
|
|||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
|
|
Loading…
Reference in New Issue