Skip to content

Commit ca60ed8

Browse files
committed
Move django-scheduler package into our codebase as ohq_schedule
- Currently, may still contain excess files that are never used - Migrate existing data from schedule tables to ohq_schedule tables
1 parent 193e95e commit ca60ed8

45 files changed

Lines changed: 3555 additions & 32 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/officehoursqueue/settings/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
"email_tools.apps.EmailToolsConfig",
5151
"accounts.apps.AccountsConfig",
5252
"ohq.apps.OhqConfig",
53-
"schedule",
53+
"ohq_schedule.apps.OHQScheduleConfig",
54+
"schedule"
5455
]
5556

5657
MIDDLEWARE = [

backend/ohq/migrations/0022_booking.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 5.0.3 on 2025-03-30 19:21
1+
# Generated by Django 5.0.3 on 2025-04-12 03:39
22

33
import django.db.models.deletion
44
from django.conf import settings
@@ -9,8 +9,7 @@ class Migration(migrations.Migration):
99

1010
dependencies = [
1111
("ohq", "0021_queue_question_timer_enabled_and_more"),
12-
("schedule", "0031_occurrence_location"),
13-
("schedule", "0037_occurrence_interval"),
12+
("ohq_schedule", "0015_event_bookable_event_interval_event_location_and_more"),
1413
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
1514
]
1615

@@ -21,10 +20,7 @@ class Migration(migrations.Migration):
2120
(
2221
"id",
2322
models.AutoField(
24-
auto_created=True,
25-
primary_key=True,
26-
serialize=False,
27-
verbose_name="ID",
23+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
2824
),
2925
),
3026
("start", models.DateTimeField(db_index=True, verbose_name="start")),
@@ -34,7 +30,7 @@ class Migration(migrations.Migration):
3430
models.ForeignKey(
3531
on_delete=django.db.models.deletion.CASCADE,
3632
related_name="bookings",
37-
to="schedule.occurrence",
33+
to="ohq_schedule.occurrence",
3834
),
3935
),
4036
(
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Generated by Django 5.0.3 on 2025-04-13 15:24
2+
3+
from django.db import migrations
4+
5+
def migrate_schedule_data(apps, schema_editor):
6+
OldCalendarRelation = apps.get_model('schedule', 'CalendarRelation')
7+
OldCalendar = apps.get_model('schedule', 'Calendar')
8+
OldEvent = apps.get_model('schedule', 'Event')
9+
OldOccurrence = apps.get_model('schedule', 'Occurrence')
10+
OldRule = apps.get_model('schedule', 'Rule')
11+
OldEventRelation = apps.get_model('schedule', 'EventRelation')
12+
13+
NewCalendarRelation = apps.get_model('ohq_schedule', 'CalendarRelation')
14+
NewCalendar = apps.get_model('ohq_schedule', 'Calendar')
15+
NewEvent = apps.get_model('ohq_schedule', 'Event')
16+
NewOccurrence = apps.get_model('ohq_schedule', 'Occurrence')
17+
NewRule = apps.get_model('ohq_schedule', 'Rule')
18+
NewEventRelation = apps.get_model('ohq_schedule', 'EventRelation')
19+
20+
for old_calendar_relation in OldCalendarRelation.objects.all():
21+
NewCalendarRelation.objects.create(
22+
id=old_calendar_relation.id,
23+
calendar_id=old_calendar_relation.calendar_id,
24+
content_type_id=old_calendar_relation.content_type_id,
25+
object_id=old_calendar_relation.object_id,
26+
distinction=old_calendar_relation.distinction,
27+
inheritable=old_calendar_relation.inheritable
28+
)
29+
30+
for old_calendar in OldCalendar.objects.all():
31+
NewCalendar.objects.create(
32+
id=old_calendar.id,
33+
name=old_calendar.name,
34+
slug=old_calendar.slug
35+
)
36+
37+
for old_rule in OldRule.objects.all():
38+
NewRule.objects.create(
39+
id=old_rule.id,
40+
name=old_rule.name,
41+
description=old_rule.description,
42+
frequency=old_rule.frequency,
43+
params=old_rule.params
44+
)
45+
46+
for old_event in OldEvent.objects.all():
47+
NewEvent.objects.create(
48+
id=old_event.id,
49+
start=old_event.start,
50+
end=old_event.end,
51+
title=old_event.title,
52+
description=old_event.description,
53+
calendar_id=old_event.calendar_id,
54+
rule_id=old_event.rule_id,
55+
end_recurring_period=old_event.end_recurring_period,
56+
location=old_event.location if hasattr(old_event, 'location') else '',
57+
bookable=old_event.bookable if hasattr(old_event, 'bookable') else False,
58+
interval=old_event.interval if hasattr(old_event, 'interval') else None
59+
)
60+
61+
for old_occurrence in OldOccurrence.objects.all():
62+
NewOccurrence.objects.create(
63+
id=old_occurrence.id,
64+
event_id=old_occurrence.event_id,
65+
title=old_occurrence.title,
66+
description=old_occurrence.description,
67+
start=old_occurrence.start,
68+
end=old_occurrence.end,
69+
cancelled=old_occurrence.cancelled,
70+
original_start=old_occurrence.original_start,
71+
original_end=old_occurrence.original_end,
72+
location=old_occurrence.location if hasattr(old_occurrence, 'location') else '',
73+
interval=old_occurrence.interval if hasattr(old_occurrence, 'interval') else None
74+
)
75+
76+
for old_relation in OldEventRelation.objects.all():
77+
NewEventRelation.objects.create(
78+
id=old_relation.id,
79+
event_id=old_relation.event_id,
80+
content_type_id=old_relation.content_type_id,
81+
object_id=old_relation.object_id,
82+
distinction=old_relation.distinction
83+
)
84+
85+
def reverse_migrate_schedule_data(apps, schema_editor):
86+
NewCalendarRelation = apps.get_model('ohq_schedule', 'CalendarRelation')
87+
NewCalendar = apps.get_model('ohq_schedule', 'Calendar')
88+
NewEvent = apps.get_model('ohq_schedule', 'Event')
89+
NewOccurrence = apps.get_model('ohq_schedule', 'Occurrence')
90+
NewRule = apps.get_model('ohq_schedule', 'Rule')
91+
NewEventRelation = apps.get_model('ohq_schedule', 'EventRelation')
92+
93+
NewCalendarRelation.objects.all().delete()
94+
NewCalendar.objects.all().delete()
95+
NewEvent.objects.all().delete()
96+
NewOccurrence.objects.all().delete()
97+
NewRule.objects.all().delete()
98+
NewEventRelation.objects.all().delete()
99+
100+
class Migration(migrations.Migration):
101+
dependencies = [
102+
('ohq', '0022_booking'),
103+
('schedule', '0001_initial'),
104+
('ohq_schedule', '0015_event_bookable_event_interval_event_location_and_more'),
105+
]
106+
operations = [
107+
migrations.RunPython(migrate_schedule_data, reverse_migrate_schedule_data),
108+
]

backend/ohq/models.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
from django.dispatch import receiver
66
from email_tools.emails import send_email
77
from phonenumber_field.modelfields import PhoneNumberField
8-
from schedule.models import Event, Occurrence
8+
from ohq_schedule.models import Event, Occurrence
9+
from schedule.models import Event as OldEvent
10+
from schedule.models import Occurrence as OldOccurrence
911

1012
User = settings.AUTH_USER_MODEL
1113

@@ -501,18 +503,6 @@ def __str__(self):
501503
end_str = self.end.strftime("%Y-%m-%d %H:%M:%S")
502504
return f"{start_str} to {end_str}"
503505

504-
Event.add_to_class('location', models.CharField(max_length=255, blank=True))
505-
Occurrence.add_to_class('location', models.CharField(max_length=255, blank=True))
506-
Occurrence.add_to_class('interval', models.IntegerField(blank=True, null=True))
507-
508-
def new_occurrence_init(self, *args, **kwargs):
509-
super(Occurrence, self).__init__(*args, **kwargs)
510-
event = kwargs.get("event", None)
511-
if not self.title and event:
512-
self.title = event.title
513-
if not self.description and event:
514-
self.description = event.description
515-
if not self.location and event:
516-
self.location = event.location
517-
518-
Occurrence.__init__ = new_occurrence_init
506+
OldEvent.add_to_class('location', models.CharField(max_length=255, blank=True))
507+
OldOccurrence.add_to_class('location', models.CharField(max_length=255, blank=True))
508+
OldOccurrence.add_to_class('interval', models.IntegerField(blank=True, null=True))

backend/ohq/permissions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.db.models import Q
22
from rest_framework import permissions
3-
from schedule.models import Event, EventRelation, Occurrence
3+
from ohq_schedule.models import Event, EventRelation, Occurrence
44
from ohq.models import (
55
Course,
66
Membership,

backend/ohq/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from phonenumber_field.serializerfields import PhoneNumberField
88
from rest_framework import serializers
99
from rest_live.signals import save_handler
10-
from schedule.models import Calendar, Event, Occurrence, EventRelation, EventRelationManager, Rule
10+
from ohq_schedule.models import Calendar, Event, Occurrence, EventRelation, EventRelationManager, Rule
1111

1212
from ohq.models import (
1313
Announcement,

backend/ohq/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from rest_framework.settings import api_settings
3333
from rest_framework.views import APIView
3434
from rest_live.mixins import RealtimeMixin
35-
from schedule.models import Event, EventRelationManager, Occurrence
35+
from ohq_schedule.models import Event, EventRelationManager, Occurrence
3636
from http import HTTPStatus
3737

3838
from ohq.filters import CourseStatisticFilter, QuestionSearchFilter, QueueStatisticFilter

backend/ohq_schedule/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import django
2+
3+
if django.VERSION < (3, 2):
4+
default_app_config = "ohq_schedule.apps.OHQScheduleConfig"

backend/ohq_schedule/admin.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from django.contrib import admin
2+
3+
from ohq_schedule.forms import EventAdminForm
4+
from ohq_schedule.models import (
5+
Calendar,
6+
CalendarRelation,
7+
Event,
8+
EventRelation,
9+
Occurrence,
10+
Rule,
11+
)
12+
13+
@admin.register(Calendar)
14+
class CalendarAdmin(admin.ModelAdmin):
15+
list_display = ("name", "slug")
16+
prepopulated_fields = {"slug": ("name",)}
17+
search_fields = ["name"]
18+
fieldsets = ((None, {"fields": [("name", "slug")]}),)
19+
20+
21+
@admin.register(CalendarRelation)
22+
class CalendarRelationAdmin(admin.ModelAdmin):
23+
list_display = ("calendar", "content_object")
24+
list_filter = ("inheritable",)
25+
fieldsets = (
26+
(
27+
None,
28+
{
29+
"fields": [
30+
"calendar",
31+
("content_type", "object_id", "distinction"),
32+
"inheritable",
33+
]
34+
},
35+
),
36+
)
37+
38+
39+
@admin.register(EventRelation)
40+
class EventRelationAdmin(admin.ModelAdmin):
41+
list_display = ("event", "content_object", "distinction")
42+
fieldsets = (
43+
(None, {"fields": ["event", ("content_type", "object_id", "distinction")]}),
44+
)
45+
46+
47+
@admin.register(Event)
48+
class EventAdmin(admin.ModelAdmin):
49+
list_display = ("title", "start", "end")
50+
list_filter = ("start",)
51+
ordering = ("-start",)
52+
date_hierarchy = "start"
53+
search_fields = ("title", "description")
54+
fieldsets = (
55+
(
56+
None,
57+
{
58+
"fields": [
59+
("title", "color_event"),
60+
("description",),
61+
("start", "end"),
62+
("creator", "calendar"),
63+
("rule", "end_recurring_period"),
64+
"location",
65+
("interval", "bookable"),
66+
]
67+
},
68+
),
69+
)
70+
form = EventAdminForm
71+
72+
73+
admin.site.register(Occurrence, admin.ModelAdmin)
74+
75+
76+
@admin.register(Rule)
77+
class RuleAdmin(admin.ModelAdmin):
78+
list_display = ("name",)
79+
list_filter = ("frequency",)
80+
search_fields = ("name", "description")

backend/ohq_schedule/apps.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from django.apps import AppConfig
2+
from django.utils.translation import gettext_lazy as _
3+
4+
5+
class OHQScheduleConfig(AppConfig):
6+
name = "ohq_schedule"
7+
verbose_name = _("ohq_schedules")
8+
default_auto_field = "django.db.models.AutoField"

0 commit comments

Comments
 (0)