diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml index 078ab2f0..07fab727 100644 --- a/.github/workflows/black.yml +++ b/.github/workflows/black.yml @@ -1,6 +1,6 @@ name: Black formatter check -on: [push] +on: [push, pull_request] jobs: black: diff --git a/media/stregsystem/background.jpg b/media/stregsystem/background.jpg new file mode 100644 index 00000000..9662d30a Binary files /dev/null and b/media/stregsystem/background.jpg differ diff --git a/media/stregsystem/easter.jpg b/media/stregsystem/easter.jpg new file mode 100644 index 00000000..d091fc46 Binary files /dev/null and b/media/stregsystem/easter.jpg differ diff --git a/requirements.txt b/requirements.txt index e00317ad..4dce3e50 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ Django==2.2.24 Pillow==8.3.2 Coverage==4.4.1 -pytz==2018.3 +pytz==2021.3 regex==2017.07.28 freezegun==0.3.15 Django-Select2==5.11.1 diff --git a/stregreport/views.py b/stregreport/views.py index 28992de0..eef48585 100644 --- a/stregreport/views.py +++ b/stregreport/views.py @@ -301,7 +301,7 @@ def ranks_for_year(request, year): 1859, ] coffee = [32, 35, 36, 39] - vitamin = [1850, 1851, 1852, 1863] + vitamin = [1850, 1851, 1852, 1863, 1880] FORMAT = '%d/%m/%Y kl. %H:%M' last_year = year - 1 diff --git a/stregsystem/admin.py b/stregsystem/admin.py index ae718c72..c873d7ec 100644 --- a/stregsystem/admin.py +++ b/stregsystem/admin.py @@ -129,6 +129,7 @@ class ProductAdmin(admin.ModelAdmin): "categories", "rooms", "alcohol_content_ml", + "caffeine_content_mg", ) readonly_fields = ("get_bought",) diff --git a/stregsystem/caffeine.py b/stregsystem/caffeine.py new file mode 100644 index 00000000..589a14e1 --- /dev/null +++ b/stregsystem/caffeine.py @@ -0,0 +1,56 @@ +from datetime import datetime, timedelta +from typing import List + +from django.utils import timezone + +CAFFEINE_IN_COFFEE = 70 +CAFFEINE_DEGRADATION_PR_HOUR = 0.12945 +CAFFEINE_TIME_INTERVAL = timedelta(days=1) + + +class Intake: + timestamp: datetime + mg: int + + def __init__(self, timestamp: datetime, mg: int): + self.timestamp = timestamp + self.mg = mg + + +def caffeine_mg_to_coffee_cups(mg: int) -> int: + return int(mg / CAFFEINE_IN_COFFEE) + + +# calculate current caffeine in body, takes list of intakes, applies caffeine degradation by using compound interest +def current_caffeine_in_body_compound_interest(intakes: List[Intake]) -> float: + """ + Given a list of Intakes (timestamp, mg), calculate caffeine mg content in blood at current time. + Assumes a bioavailability of 100%, immediate absorption in body, and caffeine half-life of 5 hours denoted by + CAFFEINE_DEGRADATION_PR_HOUR. + """ + # if no intakes withing given time interval, return 0mg in blood + if len(intakes) == 0: + return 0 + + # init last intake time to 24 hours and one minute ago to keep degradation within scope of intakes + last_intake_time = timezone.now() - timedelta(days=1, minutes=1) + mg_blood = 0 + + # append intake of 0 mg at timezone.now to intakes to calculate caffeine degradation from the latest intake to now + intakes.append(Intake(timezone.now(), 0)) + + # do compound interest on list of intakes + for intake in intakes: + # first do degradation of current caffeine in blood using compound rule (kn = k0 * (1 + r)^n), maxing to 0 + mg_blood = max( + mg_blood + * ((1 - CAFFEINE_DEGRADATION_PR_HOUR) ** ((intake.timestamp - last_intake_time) / timedelta(hours=1))), + 0, + ) + # swap curr timestamp with last intake time to calculate degradation timespan in next iteration + last_intake_time = intake.timestamp + + # finally, add current intake of caffeine to mg_blood + mg_blood += intake.mg + + return mg_blood diff --git a/stregsystem/fixtures/testdata.json b/stregsystem/fixtures/testdata.json index 4c813f8d..8cfbcb63 100644 --- a/stregsystem/fixtures/testdata.json +++ b/stregsystem/fixtures/testdata.json @@ -16,6 +16,13 @@ "notes": "This is a test user." } }, + { + "fields": { + "name": "kaffe" + }, + "model": "stregsystem.category", + "pk": "6" + }, { "model": "stregsystem.product", "pk": 1, @@ -28,12 +35,14 @@ }, { "model": "stregsystem.product", - "pk": 2, + "pk": 32, "fields": { "name": "Kold Kaffe", "price": 200, "active": true, - "deactivate_date": null + "deactivate_date": null, + "caffeine_content_mg": 70, + "categories": [6] } }, { @@ -72,7 +81,7 @@ "model": "stregsystem.oldprice", "pk": 2, "fields": { - "product": 2, + "product": 32, "price": 200, "changed_on": "2017-03-13T12:43:40.784+00:00" } @@ -81,7 +90,7 @@ "model": "stregsystem.oldprice", "pk": 3, "fields": { - "product": 2, + "product": 32, "price": 200, "changed_on": "2017-03-13T12:43:42.151+00:00" } @@ -118,7 +127,7 @@ "pk": 2, "fields": { "member": 1, - "product": 2, + "product": 32, "room": 1, "timestamp": "2017-03-13T12:54:12.423+00:00", "price": 200 diff --git a/stregsystem/forms.py b/stregsystem/forms.py index 709257b9..e33515eb 100644 --- a/stregsystem/forms.py +++ b/stregsystem/forms.py @@ -1,3 +1,5 @@ +import datetime + from django import forms from stregsystem.models import MobilePayment, Member @@ -31,3 +33,18 @@ class QRPaymentForm(forms.Form): class PurchaseForm(forms.Form): product_id = forms.IntegerField() + + +class RankingDateForm(forms.Form): + from_date = forms.DateField(widget=forms.SelectDateWidget(years=range(2000, datetime.date.today().year + 1))) + to_date = forms.DateField( + initial=datetime.date.today(), widget=forms.SelectDateWidget(years=range(2000, datetime.date.today().year + 1)) + ) + + # validate form. make sure that from_date is before to_date + def clean(self): + cleaned_data = super().clean() + if cleaned_data['from_date'] > cleaned_data['to_date']: + # raise forms.ValidationError('Fra dato skal være før eller lig til dato') + self.add_error('to_date', 'Fra dato skal være før eller lig til dato') + return cleaned_data diff --git a/stregsystem/migrations/0015_product_caffeine_content_mg.py b/stregsystem/migrations/0015_product_caffeine_content_mg.py new file mode 100644 index 00000000..93163ad8 --- /dev/null +++ b/stregsystem/migrations/0015_product_caffeine_content_mg.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.24 on 2021-11-30 12:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stregsystem', '0014_mobilepayment_nullable_customername_20210908_1522'), + ] + + operations = [ + migrations.AddField( + model_name='product', + name='caffeine_content_mg', + field=models.IntegerField(default=0), + ), + ] diff --git a/stregsystem/models.py b/stregsystem/models.py index 9452b066..b4bed2c8 100644 --- a/stregsystem/models.py +++ b/stregsystem/models.py @@ -1,3 +1,4 @@ +import datetime from collections import Counter from email.utils import parseaddr @@ -8,6 +9,7 @@ from django.db.models import Count from django.utils import timezone +from stregsystem.caffeine import Intake, CAFFEINE_TIME_INTERVAL, current_caffeine_in_body_compound_interest from stregsystem.deprecated import deprecated from stregsystem.templatetags.stregsystem_extras import money from stregsystem.utils import ( @@ -287,6 +289,35 @@ def calculate_alcohol_promille(self): return bac + def calculate_caffeine_in_body(self) -> float: + # get list of last 24h caffeine intakes and calculate current body caffeine content + return current_caffeine_in_body_compound_interest( + [ + Intake(x.timestamp, x.product.caffeine_content_mg) + for x in self.sale_set.filter( + timestamp__gt=timezone.now() - CAFFEINE_TIME_INTERVAL, product__caffeine_content_mg__gt=0 + ).order_by('timestamp') + ] + ) + + def is_leading_coffee_addict(self): + coffee_category = [6] + + now = timezone.now() + start_of_week = now - datetime.timedelta(days=now.weekday()) - datetime.timedelta(hours=now.hour) + user_with_most_coffees_bought = ( + Member.objects.filter( + sale__timestamp__gt=start_of_week, + sale__timestamp__lte=now, + sale__product__categories__in=coffee_category, + ) + .annotate(Count('sale')) + .order_by('-sale__count', 'username') + .first() + ) + + return user_with_most_coffees_bought == self + class Payment(models.Model): # id automatisk... class Meta: @@ -311,7 +342,8 @@ def __unicode__(self): def __str__(self): return self.member.username + " " + str(self.timestamp) + ": " + money(self.amount) - def save(self, *args, **kwargs): + @transaction.atomic + def save(self, mbpayment=None, *args, **kwargs): if self.id: return # update -- should not be allowed else: @@ -321,7 +353,7 @@ def save(self, *args, **kwargs): self.member.save() if self.member.email != "" and self.amount != 0: if '@' in parseaddr(self.member.email)[1] and self.member.want_spam: - send_payment_mail(self.member, self.amount) + send_payment_mail(self.member, self.amount, mbpayment.comment if mbpayment else None) def log_from_mobile_payment(self, processed_mobile_payment, admin_user: User): LogEntry.objects.log_action( @@ -447,7 +479,7 @@ def process_submitted_mobile_payments(submitted_data, admin_user: User): payment = Payment(member=member, amount=payment_amount) payment.log_from_mobile_payment(processed_mobile_payment, admin_user) - payment.save() + payment.save(mbpayment=processed_mobile_payment) processed_mobile_payment.payment = payment processed_mobile_payment.member = member @@ -517,6 +549,7 @@ class Product(models.Model): # id automatisk... categories = models.ManyToManyField(Category, blank=True) rooms = models.ManyToManyField(Room, blank=True) alcohol_content_ml = models.FloatField(default=0.0, null=True) + caffeine_content_mg = models.IntegerField(default=0) @deprecated def __unicode__(self): diff --git a/stregsystem/static/stregsystem/beerflake.gif b/stregsystem/static/stregsystem/beerflake.gif new file mode 100644 index 00000000..af7de299 Binary files /dev/null and b/stregsystem/static/stregsystem/beerflake.gif differ diff --git a/stregsystem/static/stregsystem/beerflakeCursed.gif b/stregsystem/static/stregsystem/beerflakeCursed.gif new file mode 100644 index 00000000..b42f966a Binary files /dev/null and b/stregsystem/static/stregsystem/beerflakeCursed.gif differ diff --git a/stregsystem/static/stregsystem/easter.css b/stregsystem/static/stregsystem/easter.css new file mode 100644 index 00000000..f3b1167a --- /dev/null +++ b/stregsystem/static/stregsystem/easter.css @@ -0,0 +1,208 @@ +.kylle{ + position: fixed; + top: 72%; + right:-42%; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + animation-name: play; + animation-duration: 60s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-play-state: running; +} + +@keyframes play { + 0%,80% {right:-80%;} + 100%{right:180%;} +} +.easter-container { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; +} + +@keyframes beerflakes-fall { + 0% { + top: -10% + } + 100% { + top: 100% + } +} + +@keyframes beerflakes-shake { + 0% { + transform: translateX(0px) + } + 50% { + transform: translateX(80px) + } + 100% { + transform: translateX(0px) + } +} + +.beerflake { + position: fixed; + top: -30%; + background: transparent; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + animation-name: beerflakes-fall, beerflakes-shake; + animation-duration: 10s, 3s; + animation-timing-function: linear, ease-in-out; + animation-iteration-count: infinite, infinite; + animation-play-state: running, running; +} + +.beerflake:nth-of-type(0) { + left: 1%; + -webkit-animation-delay: 0s, 0s; + animation-delay: 0s, 0s +} + +.beerflake:nth-of-type(1) { + left: 10%; + -webkit-animation-delay: 1s, 1s; + animation-delay: 1s, 1s +} + +.beerflake:nth-of-type(2) { + left: 20%; + -webkit-animation-delay: 6s, .5s; + animation-delay: 6s, .5s +} + +.beerflake:nth-of-type(3) { + left: 30%; + -webkit-animation-delay: 4s, 2s; + animation-delay: 4s, 2s +} + +.beerflake:nth-of-type(4) { + left: 40%; + -webkit-animation-delay: 2s, 2s; + animation-delay: 2s, 2s +} + +.beerflake:nth-of-type(5) { + left: 50%; + -webkit-animation-delay: 8s, 3s; + animation-delay: 8s, 3s +} + +.beerflake:nth-of-type(6) { + left: 60%; + -webkit-animation-delay: 6s, 2s; + animation-delay: 6s, 2s +} + +.beerflake:nth-of-type(7) { + left: 70%; + -webkit-animation-delay: 2.5s, 1s; + animation-delay: 2.5s, 1s +} + +.beerflake:nth-of-type(8) { + left: 80%; + -webkit-animation-delay: 1s, 0s; + animation-delay: 1s, 0s +} + +.beerflake:nth-of-type(9) { + left: 90%; + -webkit-animation-delay: 7s, 4s; + animation-delay: 2.5s, 5.77s +} + +.beerflake:nth-of-type(10) { + left: 5%; + -webkit-animation-delay: 5.69s, 7.5s; + animation-delay: 7s, 5.77s +} + +.beerflake:nth-of-type(11) { + left: 15%; + -webkit-animation-delay: 12s, 12.9s; + animation-delay: 17s, 7.5s +} + +.beerflake:nth-of-type(12) { + left: 25%; + -webkit-animation-delay: 5.69s, 4s; + animation-delay: 2.5s, 4s +} + +.beerflake:nth-of-type(13) { + left: 35%; + -webkit-animation-delay: 7s, 6s; + animation-delay: 7s, 8s +} + +.beerflake:nth-of-type(14) { + left: 45%; + -webkit-animation-delay: 4s, 12.9s; + animation-delay: 5.69s, 7.5s +} + +.beerflake:nth-of-type(15) { + left: 55%; + -webkit-animation-delay: 2.5s, 1s; + animation-delay: 7s, 4s +} + +.beerflake:nth-of-type(16) { + left: 65%; + -webkit-animation-delay: 8s, 6s; + animation-delay: 2.5s, 3.2s +} + +.beerflake:nth-of-type(17) { + left: 75%; + -webkit-animation-delay: 7s, 2.5s; + animation-delay: 2.5s, 7.5s +} + +.beerflake:nth-of-type(18) { + left: 85%; + -webkit-animation-delay: 8.5s, 12.9s; + animation-delay: 5.69s, 4s +} + +.beerflake:nth-of-type(19) { + left: 95%; + -webkit-animation-delay: 2.5s, 6s; + animation-delay: 4s, 12.9s +} + +.beerflake:nth-of-type(20) { + left: 3%; + -webkit-animation-delay: 7s, 2.5s; + animation-delay: 13s, 4s +} + +.beerflake:nth-of-type(21) { + left: 13%; + -webkit-animation-delay: 5.77s, 6s; + animation-delay: 2.5s, 4s +} + +.beerflake:nth-of-type(22) { + left: 42%; + -webkit-animation-delay: 7s, 4s; + animation-delay: 5.69s, 7.5s +} + +.beerflake:nth-of-type(23) { + left: 69%; + -webkit-animation-delay: 2.5s, 4s; + animation-delay: 42s, 12.9s +} diff --git a/stregsystem/static/stregsystem/easter.js b/stregsystem/static/stregsystem/easter.js new file mode 100644 index 00000000..d7f44b69 --- /dev/null +++ b/stregsystem/static/stregsystem/easter.js @@ -0,0 +1,58 @@ +d = new Date(); + +if(d.getMonth() === 3){ + if(d.getHours() === 13 && d.getMinutes() === 37){ + for(let beerflakes=0; beerflakes < Math.min(d.getDate(), 24); beerflakes++){ + SpawnBeerflakeCursed(); + } + }else{ + for(let beerflakes=0; beerflakes < Math.min(d.getDate(), 24); beerflakes++){ + SpawnBeerflake(); + } + } + + const kylle = document.createElement('div'); + kylle.classList.add("kylle"); + const gif = document.createElement("img") + if(d.getHours() === 13 && d.getMinutes() === 37){ + gif.src="/static/stregsystem/kylleCursed.gif"; + kylle.setAttribute('style', 'top: 60%'); + }else{ + gif.src="/static/stregsystem/kylle.gif"; + } + kylle.appendChild(gif); + document.body.querySelector(".easter-container").appendChild(kylle); + + SetBodyEasterStyle(); +} + +function SpawnBeerflakeCursed () { + const beerflakeCursed = document.createElement('div'); + beerflakeCursed.classList.add("beerflake"); + const gif = document.createElement("img") + gif.src="/static/stregsystem/beerflakeCursed.gif"; + beerflakeCursed.appendChild(gif); + document.body.querySelector(".easter-container").appendChild(beerflakeCursed); +} + +function SpawnBeerflake () { + const beerflake = document.createElement('div'); + beerflake.classList.add("beerflake"); + const gif = document.createElement("img") + gif.src="/static/stregsystem/beerflake.gif"; + beerflake.appendChild(gif); + document.body.querySelector(".easter-container").appendChild(beerflake); +} + +function SetBodyEasterStyle() { + const bodyStyle = document.body.style; + bodyStyle.color = "black"; + bodyStyle.backgroundImage = "url(\"" + media_url + "stregsystem/easter.jpg\")"; + bodyStyle.backgroundRepeat = "repeat-x"; + bodyStyle.backgroundSize = "auto 100%"; + bodyStyle.padding = "0"; + bodyStyle.margin = "0"; + bodyStyle.width = "100vw"; + bodyStyle.height = "100vh"; + bodyStyle.position = "relative"; +} \ No newline at end of file diff --git a/stregsystem/static/stregsystem/kylle.gif b/stregsystem/static/stregsystem/kylle.gif new file mode 100644 index 00000000..87ea2c37 Binary files /dev/null and b/stregsystem/static/stregsystem/kylle.gif differ diff --git a/stregsystem/static/stregsystem/kylleCursed.gif b/stregsystem/static/stregsystem/kylleCursed.gif new file mode 100644 index 00000000..4da1a0f5 Binary files /dev/null and b/stregsystem/static/stregsystem/kylleCursed.gif differ diff --git a/stregsystem/static/stregsystem/santa-sled.gif b/stregsystem/static/stregsystem/santa-sled.gif new file mode 100644 index 00000000..91487ca2 Binary files /dev/null and b/stregsystem/static/stregsystem/santa-sled.gif differ diff --git a/stregsystem/static/stregsystem/snow.css b/stregsystem/static/stregsystem/snow.css new file mode 100644 index 00000000..d519ec36 --- /dev/null +++ b/stregsystem/static/stregsystem/snow.css @@ -0,0 +1,209 @@ +.santa{ + position: fixed; + top: 72%; + right:-42%; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + animation-name: play; + animation-duration: 60s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-play-state: running; +} + +@keyframes play { + 0%,80% {right:-80%;} + 100%{right:180%;} +} +.snow-container { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; +} + +@keyframes snowflakes-fall { + 0% { + top: -10% + } + 100% { + top: 100% + } +} + +@keyframes snowflakes-shake { + 0% { + transform: translateX(0px) + } + 50% { + transform: translateX(80px) + } + 100% { + transform: translateX(0px) + } +} + +.snowflake { + --size: 1vw; + width: var(--size); + height: var(--size); + background: white; + border-radius: 50%; + position: fixed; + top: -10%; + z-index: 9999; + cursor: default; + animation-name: snowflakes-fall, snowflakes-shake; + animation-duration: 10s, 3s; + animation-timing-function: linear, ease-in-out; + animation-iteration-count: infinite, infinite; + animation-play-state: running, running +} + +.snowflake:nth-of-type(0) { + left: 1%; + -webkit-animation-delay: 0s, 0s; + animation-delay: 0s, 0s +} + +.snowflake:nth-of-type(1) { + left: 10%; + -webkit-animation-delay: 1s, 1s; + animation-delay: 1s, 1s +} + +.snowflake:nth-of-type(2) { + left: 20%; + -webkit-animation-delay: 6s, .5s; + animation-delay: 6s, .5s +} + +.snowflake:nth-of-type(3) { + left: 30%; + -webkit-animation-delay: 4s, 2s; + animation-delay: 4s, 2s +} + +.snowflake:nth-of-type(4) { + left: 40%; + -webkit-animation-delay: 2s, 2s; + animation-delay: 2s, 2s +} + +.snowflake:nth-of-type(5) { + left: 50%; + -webkit-animation-delay: 8s, 3s; + animation-delay: 8s, 3s +} + +.snowflake:nth-of-type(6) { + left: 60%; + -webkit-animation-delay: 6s, 2s; + animation-delay: 6s, 2s +} + +.snowflake:nth-of-type(7) { + left: 70%; + -webkit-animation-delay: 2.5s, 1s; + animation-delay: 2.5s, 1s +} + +.snowflake:nth-of-type(8) { + left: 80%; + -webkit-animation-delay: 1s, 0s; + animation-delay: 1s, 0s +} + +.snowflake:nth-of-type(9) { + left: 90%; + -webkit-animation-delay: 7s, 4s; + animation-delay: 2.5s, 5.77s +} + +.snowflake:nth-of-type(10) { + left: 5%; + -webkit-animation-delay: 5.69s, 7.5s; + animation-delay: 7s, 5.77s +} + +.snowflake:nth-of-type(11) { + left: 15%; + -webkit-animation-delay: 12s, 12.9s; + animation-delay: 17s, 7.5s +} + +.snowflake:nth-of-type(12) { + left: 25%; + -webkit-animation-delay: 5.69s, 4s; + animation-delay: 2.5s, 4s +} + +.snowflake:nth-of-type(13) { + left: 35%; + -webkit-animation-delay: 7s, 6s; + animation-delay: 7s, 8s +} + +.snowflake:nth-of-type(14) { + left: 45%; + -webkit-animation-delay: 4s, 12.9s; + animation-delay: 5.69s, 7.5s +} + +.snowflake:nth-of-type(15) { + left: 55%; + -webkit-animation-delay: 2.5s, 1s; + animation-delay: 7s, 4s +} + +.snowflake:nth-of-type(16) { + left: 65%; + -webkit-animation-delay: 8s, 6s; + animation-delay: 2.5s, 3.2s +} + +.snowflake:nth-of-type(17) { + left: 75%; + -webkit-animation-delay: 7s, 2.5s; + animation-delay: 2.5s, 7.5s +} + +.snowflake:nth-of-type(18) { + left: 85%; + -webkit-animation-delay: 8.5s, 12.9s; + animation-delay: 5.69s, 4s +} + +.snowflake:nth-of-type(19) { + left: 95%; + -webkit-animation-delay: 2.5s, 6s; + animation-delay: 4s, 12.9s +} + +.snowflake:nth-of-type(20) { + left: 3%; + -webkit-animation-delay: 7s, 2.5s; + animation-delay: 13s, 4s +} + +.snowflake:nth-of-type(21) { + left: 13%; + -webkit-animation-delay: 5.77s, 6s; + animation-delay: 2.5s, 4s +} + +.snowflake:nth-of-type(22) { + left: 42%; + -webkit-animation-delay: 7s, 4s; + animation-delay: 5.69s, 7.5s +} + +.snowflake:nth-of-type(23) { + left: 69%; + -webkit-animation-delay: 2.5s, 4s; + animation-delay: 42s, 12.9s +} diff --git a/stregsystem/static/stregsystem/snow.js b/stregsystem/static/stregsystem/snow.js new file mode 100644 index 00000000..226b9362 --- /dev/null +++ b/stregsystem/static/stregsystem/snow.js @@ -0,0 +1,35 @@ +d = new Date(); + +if(d.getMonth() === 11){ + for(let snowflakes=0; snowflakes < Math.min(d.getDate(), 24); snowflakes++){ + SpawnSnowflake(); + } + + const santa = document.createElement('div'); + santa.classList.add("santa"); + const gif = document.createElement("img") + gif.src="/static/stregsystem/santa-sled.gif"; + santa.appendChild(gif); + document.body.querySelector(".snow-container").appendChild(santa); + + SetBodyChristmasStyle(); +} + +function SpawnSnowflake () { + const snowflake = document.createElement('div'); + snowflake.classList.add("snowflake"); + document.body.querySelector(".snow-container").appendChild(snowflake); +} + +function SetBodyChristmasStyle() { + const bodyStyle = document.body.style; + bodyStyle.color = "white"; + bodyStyle.backgroundImage = "url(\"" + media_url + "stregsystem/background.jpg\")"; + bodyStyle.backgroundRepeat = "repeat-x"; + bodyStyle.backgroundSize = "auto 100%"; + bodyStyle.padding = "0"; + bodyStyle.margin = "0"; + bodyStyle.width = "100vw"; + bodyStyle.height = "100vh"; + bodyStyle.position = "relative" +} \ No newline at end of file diff --git a/stregsystem/static/stregsystem/stregsystem.css b/stregsystem/static/stregsystem/stregsystem.css index e0198918..8ae899fc 100644 --- a/stregsystem/static/stregsystem/stregsystem.css +++ b/stregsystem/static/stregsystem/stregsystem.css @@ -1,7 +1,6 @@ body { color: black; background-color: white; -/* text-align: center;*/ } h1 { color: red } diff --git a/stregsystem/templates/stregsystem/base.html b/stregsystem/templates/stregsystem/base.html index 12bcb35b..16229e0d 100644 --- a/stregsystem/templates/stregsystem/base.html +++ b/stregsystem/templates/stregsystem/base.html @@ -12,6 +12,8 @@ + + + +
- + + {% show_candle %}