Compare commits

..

23 Commits

Author SHA1 Message Date
flo 678397efc0 Update dependency gunicorn to v26 2026-05-05 07:01:12 +00:00
flo 4d825f3b28 overhaul site for 2026: amber theme, archive pages, consolidated main page
- Update site title and dates to 2026 (11.-14. Juni)
- New amber/fire color scheme replacing the old green
- Archive 2022 and 2024 as single combined Django pages (news, program, A-Z, Bühne & Technik, Finanzen)
- Archive pages use a neutral blue-grey color scheme for content
- Remove standalone atoz, program, finance pages; consolidate into main Festival page
- Main page now has Über uns intro, Programm (2026 lineup), Von A bis Z, Finanzen sections
- Footer with archive links instead of nav entries
- Nav simplified to Festival and für Bands

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 20:07:51 +02:00
flo 5ec8b93441 fix volume for postrges 18 db 2026-03-30 19:20:09 +02:00
flo 16e0c5e3a6 Merge pull request 'Update dependency ruff to v0.15.8' (#20) from renovate/ruff-0.x into main
Reviewed-on: #20
2026-03-30 17:18:13 +00:00
flo b3be4c6be1 Merge pull request 'Update dependency gunicorn to v25.3.0' (#21) from renovate/gunicorn-25.x into main
Reviewed-on: #21
2026-03-30 17:18:01 +00:00
flo d8ceb6af8e Update dependency gunicorn to v25.3.0 2026-03-27 07:01:04 +00:00
flo cc72b3f32d Update dependency ruff to v0.15.8 2026-03-27 07:00:52 +00:00
flo de8fd5e3cc Merge pull request 'Update dependency django to v6.0.3' (#19) from renovate/django-6.x into main
Reviewed-on: #19
2026-03-12 11:32:41 +00:00
flo 3bfe7340ca Merge pull request 'Update dependency ruff to v0.15.5' (#18) from renovate/ruff-0.x into main
Reviewed-on: #18
2026-03-12 11:31:39 +00:00
flo d38c0d0a24 Update dependency ruff to v0.15.5 2026-03-06 07:00:57 +00:00
flo 0d6f7bdd3a Update dependency django to v6.0.3 2026-03-03 17:00:56 +00:00
flo 91571bf935 Merge pull request 'Update dependency ruff to v0.15.2' (#17) from renovate/ruff-0.x into main
Reviewed-on: #17
2026-02-23 22:26:16 +00:00
flo 22c85b5032 change workdir and fix uv venv usage 2026-02-21 12:19:49 +01:00
flo 62eb864c18 Update dependency ruff to v0.15.2 2026-02-20 07:00:57 +00:00
flo 1793be90e1 reformat using prettier 2026-02-19 18:53:08 +01:00
flo acd8e8a52a add editorconfig 2026-02-19 18:48:38 +01:00
flo 8a1a5ac000 update dependencies and add ruff 2026-02-19 18:42:42 +01:00
flo 10d3254dda reformat everything using ruff 2026-02-19 18:32:01 +01:00
flo 5b48167c66 replace pip with uv 2026-02-19 18:31:21 +01:00
flo 683c73421f Merge pull request 'Update dependency django to v6.0.2' (#15) from renovate/django-6.x into main
Reviewed-on: #15
2026-02-19 16:44:07 +00:00
flo d4aeb50af9 Merge pull request 'Update dependency psycopg to v3.3.3' (#16) from renovate/psycopg-3.x into main
Reviewed-on: #16
2026-02-19 16:41:14 +00:00
flo b58800a935 Update dependency psycopg to v3.3.3 2026-02-18 17:01:07 +00:00
flo 25e2cd72f5 Update dependency django to v6.0.2 2026-02-03 17:01:22 +00:00
25 changed files with 1255 additions and 601 deletions
+10
View File
@@ -0,0 +1,10 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 120
trim_trailing_whitespace = true
+6 -4
View File
@@ -1,8 +1,10 @@
FROM python:3.14-alpine
ENV PYTHONUNBUFFERED=1
WORKDIR /code/
COPY requirements.txt .
RUN pip install --upgrade pip && \
pip install --no-cache-dir --requirement requirements.txt
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
WORKDIR /app
COPY pyproject.toml .
ENV VIRTUAL_ENV=/opt/venv
RUN uv venv $VIRTUAL_ENV && uv pip install -r pyproject.toml
ENV PATH="/opt/venv/bin:$PATH"
COPY . .
ENTRYPOINT ["./entrypoint.sh"]
+27 -28
View File
@@ -1,30 +1,29 @@
services:
db:
image: postgres:18-alpine
init: true
environment:
POSTGRES_DB: "gaehsnitzdb"
POSTGRES_USER: "gaehsnitzuser"
POSTGRES_PASSWORD: "SCKL97ukwICPpjJ9rXyhdljZ86T29A"
expose:
- "5432"
volumes:
- ./volumes/db/postgresql:/var/lib/postgresql:rw
db:
image: postgres:18-alpine
init: true
environment:
POSTGRES_DB: "gaehsnitzdb"
POSTGRES_USER: "gaehsnitzuser"
POSTGRES_PASSWORD: "SCKL97ukwICPpjJ9rXyhdljZ86T29A"
expose:
- "5432"
volumes:
- ./volumes/db/data:/var/lib/postgresql/data:rw
web:
build:
context: .
init: true
environment:
DB_HOST: "db"
DB_PORT: "5432"
DB_NAME: "gaehsnitzdb"
DB_USER: "gaehsnitzuser"
DB_PASSWORD: "SCKL97ukwICPpjJ9rXyhdljZ86T29A"
depends_on:
- db
ports:
- "80:8000"
volumes:
- .:/code:rw
web:
build:
context: .
init: true
environment:
DB_HOST: "db"
DB_PORT: "5432"
DB_NAME: "gaehsnitzdb"
DB_USER: "gaehsnitzuser"
DB_PASSWORD: "SCKL97ukwICPpjJ9rXyhdljZ86T29A"
depends_on:
- db
ports:
- "80:8000"
volumes:
- .:/app
+91 -54
View File
@@ -20,17 +20,18 @@ class CustomUserAdmin(UserAdmin):
ordering = ("username",)
list_filter = []
fieldsets = (
(None, {"fields": (
"username",
"password",
)}),
("BALANCE", {"fields": (
"consumed_drinks_price",
)}),
)
readonly_fields = (
"consumed_drinks_price",
(
None,
{
"fields": (
"username",
"password",
)
},
),
("BALANCE", {"fields": ("consumed_drinks_price",)}),
)
readonly_fields = ("consumed_drinks_price",)
inlines = (ConsumptionInline,)
def consumed_drinks_price(self, user: User):
@@ -61,52 +62,88 @@ class PaymentAdmin(admin.ModelAdmin):
class DrinkAdmin(admin.ModelAdmin):
list_display = ("name", "purchase_price_per_crate", "crates_purchased", "purchase_price_total")
fieldsets = (
(None, {"fields": (
"name",
)}),
("crates", {"fields": (
"crates_ordered",
"crates_purchased",
"crates_returned",
)}),
("bottles", {"fields": (
"bottles_per_crate",
"bottles_total",
"bottles_returned",
)}),
("amount", {"fields": (
"bottle_size",
"amount_per_crate",
"amount_total",
)}),
("purchase", {"fields": (
"purchase_price_per_crate",
"purchase_price_per_bottle",
"purchase_price_total",
)}),
("deposit", {"fields": (
"deposit_per_crate",
"deposit_total",
"deposit_refund",
"deposit_kept",
)}),
("sales", {"fields": (
"sale_price_per_bottle",
"bottles_sold",
"sales_purchase_value",
"sale_price_total",
"bottles_given_away",
"giveaway_purchase_value",
"balance",
)}),
(None, {"fields": ("name",)}),
(
"crates",
{
"fields": (
"crates_ordered",
"crates_purchased",
"crates_returned",
)
},
),
(
"bottles",
{
"fields": (
"bottles_per_crate",
"bottles_total",
"bottles_returned",
)
},
),
(
"amount",
{
"fields": (
"bottle_size",
"amount_per_crate",
"amount_total",
)
},
),
(
"purchase",
{
"fields": (
"purchase_price_per_crate",
"purchase_price_per_bottle",
"purchase_price_total",
)
},
),
(
"deposit",
{
"fields": (
"deposit_per_crate",
"deposit_total",
"deposit_refund",
"deposit_kept",
)
},
),
(
"sales",
{
"fields": (
"sale_price_per_bottle",
"bottles_sold",
"sales_purchase_value",
"sale_price_total",
"bottles_given_away",
"giveaway_purchase_value",
"balance",
)
},
),
)
readonly_fields = (
"bottles_total", "bottles_returned",
"amount_per_crate", "amount_total",
"purchase_price_per_bottle", "purchase_price_total",
"deposit_total", "deposit_refund", "deposit_kept",
"bottles_sold", "sales_purchase_value", "sale_price_total",
"bottles_given_away", "giveaway_purchase_value",
"bottles_total",
"bottles_returned",
"amount_per_crate",
"amount_total",
"purchase_price_per_bottle",
"purchase_price_total",
"deposit_total",
"deposit_refund",
"deposit_kept",
"bottles_sold",
"sales_purchase_value",
"sale_price_total",
"bottles_given_away",
"giveaway_purchase_value",
"balance",
)
+94 -72
View File
@@ -46,16 +46,14 @@ def payback(user, day, month, amount, note):
def consumption(day: int, for_free: bool, drink_dict: Dict[User, List[Tuple[int, Drink]]]):
for user, drink_list in drink_dict.items():
for amount, drink in drink_list:
Consumption.objects.create(
user=user, drink=drink, amount=amount, day=day, for_free=for_free)
Consumption.objects.create(user=user, drink=drink, amount=amount, day=day, for_free=for_free)
class Command(BaseCommand):
@transaction.atomic()
def handle(self, *args, **options):
if any(model.objects.exists() for model in [Donation, Payment, Drink, Consumption]):
raise CommandError(
"clear all donation, payment, drink and consumption objects before running this command")
raise CommandError("clear all donation, payment, drink and consumption objects before running this command")
# --------------- PEOPLE ---------------
@@ -224,82 +222,106 @@ class Command(BaseCommand):
# --------------- THURSDAY ---------------
consumption(day=1, for_free=False, drink_dict={
robert: [(2, mate), (2, radler), (1, wasser)],
thure: [(4, sterni), (1, krosti), (2, radler)],
tobi: [(7, sterni), (2, krosti)],
herald: [(1, radler), (2, wasser), (4, wein)],
annemarie: [(1, sterni), (1, wasser), (2, wein)],
cathi_clemens: [(1, sterni), (2, radler)],
flo: [(6, sterni), (1, wasser)],
josi: [(4, sterni)],
aimee: [(5, sterni)],
lutz: [(1, sterni), (1, wasser)],
lasse: [(2, sterni), (1, wasser)],
domi: [(1, sterni), (1, radler)],
})
consumption(day=1, for_free=True, drink_dict={
seth_family: [(1, krosti), (1, radler)],
})
consumption(
day=1,
for_free=False,
drink_dict={
robert: [(2, mate), (2, radler), (1, wasser)],
thure: [(4, sterni), (1, krosti), (2, radler)],
tobi: [(7, sterni), (2, krosti)],
herald: [(1, radler), (2, wasser), (4, wein)],
annemarie: [(1, sterni), (1, wasser), (2, wein)],
cathi_clemens: [(1, sterni), (2, radler)],
flo: [(6, sterni), (1, wasser)],
josi: [(4, sterni)],
aimee: [(5, sterni)],
lutz: [(1, sterni), (1, wasser)],
lasse: [(2, sterni), (1, wasser)],
domi: [(1, sterni), (1, radler)],
},
)
consumption(
day=1,
for_free=True,
drink_dict={
seth_family: [(1, krosti), (1, radler)],
},
)
# --------------- FRIDAY ---------------
consumption(day=2, for_free=False, drink_dict={
robert: [(2, mate), (1, radler)],
thure: [(8, sterni), (2, krosti), (1, wasser)],
tobi: [(2, mate), (5, sterni), (5, krosti), (3, radler), (1, cola)],
herald: [(1, mate), (1, sterni), (2, radler), (1, cola), (4, wasser), (7, wein)],
annemarie: [(2, mate), (9, sterni), (1, krosti), (2, radler), (3, wasser)],
cathi_clemens: [(3, sterni), (3, radler)],
flo: [(1, mate), (6, sterni), (3, wasser)],
josi: [(8, sterni), (1, krosti), (2, radler)],
andrew: [(4, sterni)],
peter: [(7, sterni), (1, krosti), (2, wasser)],
fiddi_melli: [(6, sterni), (3, radler), (1, wasser)],
suse: [(1, krosti), (1, radler)],
lilly_simon: [(1, mate), (7, sterni), (3, wasser)]
})
consumption(
day=2,
for_free=False,
drink_dict={
robert: [(2, mate), (1, radler)],
thure: [(8, sterni), (2, krosti), (1, wasser)],
tobi: [(2, mate), (5, sterni), (5, krosti), (3, radler), (1, cola)],
herald: [(1, mate), (1, sterni), (2, radler), (1, cola), (4, wasser), (7, wein)],
annemarie: [(2, mate), (9, sterni), (1, krosti), (2, radler), (3, wasser)],
cathi_clemens: [(3, sterni), (3, radler)],
flo: [(1, mate), (6, sterni), (3, wasser)],
josi: [(8, sterni), (1, krosti), (2, radler)],
andrew: [(4, sterni)],
peter: [(7, sterni), (1, krosti), (2, wasser)],
fiddi_melli: [(6, sterni), (3, radler), (1, wasser)],
suse: [(1, krosti), (1, radler)],
lilly_simon: [(1, mate), (7, sterni), (3, wasser)],
},
)
consumption(day=2, for_free=True, drink_dict={
seth_family: [(1, mate), (6, sterni), (3, wasser)],
aimee: [(1, mate), (9, sterni), (3, wasser)],
lutz: [(1, mate), (9, sterni), (3, wasser)],
lasse: [(7, sterni), (1, wasser)],
domi: [(1, mate), (4, sterni), (1, wasser)],
hans_welle: [(3, mate), (7, sterni), (7, krosti), (1, cola), (2, wasser)],
})
consumption(
day=2,
for_free=True,
drink_dict={
seth_family: [(1, mate), (6, sterni), (3, wasser)],
aimee: [(1, mate), (9, sterni), (3, wasser)],
lutz: [(1, mate), (9, sterni), (3, wasser)],
lasse: [(7, sterni), (1, wasser)],
domi: [(1, mate), (4, sterni), (1, wasser)],
hans_welle: [(3, mate), (7, sterni), (7, krosti), (1, cola), (2, wasser)],
},
)
# --------------- SATURDAY ---------------
consumption(day=3, for_free=False, drink_dict={
robert: [(4, mate), (1, cola), (4, wasser)],
tobi: [(9, sterni), (1, krosti), (2, radler), (1, cola)],
herald: [(2, mate), (2, radler), (3, wasser), (5, wein)],
annemarie: [(2, mate), (6, sterni), (3, radler), (1, cola), (1, wasser)],
cathi_clemens: [(4, sterni), (8, radler), (1, wasser)],
flo: [(2, mate), (8, sterni), (1, radler), (3, wasser)],
josi: [(9, sterni), (2, radler), (2, wasser)],
aimee: [(10, sterni), (2, radler)],
lutz: [(1, krosti), (1, wasser)],
lasse: [(1, mate), (8, sterni)],
domi: [(6, sterni), (2, radler), (1, wasser)],
peter: [(3, sterni), (3, krosti), (2, radler)],
fiddi_melli: [(1, mate), (1, wasser)],
suse: [(1, mate), (1, sterni), (2, krosti), (4, radler)],
lilly_simon: [(1, mate), (2, radler), (7, wasser)],
kevin: [(1, mate), (1, radler)],
rebecca: [(1, radler)],
resi_simon: [(8, sterni), (1, radler), (1, wasser)],
})
consumption(
day=3,
for_free=False,
drink_dict={
robert: [(4, mate), (1, cola), (4, wasser)],
tobi: [(9, sterni), (1, krosti), (2, radler), (1, cola)],
herald: [(2, mate), (2, radler), (3, wasser), (5, wein)],
annemarie: [(2, mate), (6, sterni), (3, radler), (1, cola), (1, wasser)],
cathi_clemens: [(4, sterni), (8, radler), (1, wasser)],
flo: [(2, mate), (8, sterni), (1, radler), (3, wasser)],
josi: [(9, sterni), (2, radler), (2, wasser)],
aimee: [(10, sterni), (2, radler)],
lutz: [(1, krosti), (1, wasser)],
lasse: [(1, mate), (8, sterni)],
domi: [(6, sterni), (2, radler), (1, wasser)],
peter: [(3, sterni), (3, krosti), (2, radler)],
fiddi_melli: [(1, mate), (1, wasser)],
suse: [(1, mate), (1, sterni), (2, krosti), (4, radler)],
lilly_simon: [(1, mate), (2, radler), (7, wasser)],
kevin: [(1, mate), (1, radler)],
rebecca: [(1, radler)],
resi_simon: [(8, sterni), (1, radler), (1, wasser)],
},
)
consumption(day=3, for_free=True, drink_dict={
thure: [(1, mate), (4, sterni), (5, radler), (3, wasser)],
seth_family: [(1, mate), (2, sterni), (12, krosti), (1, wasser)],
andrew: [(3, sterni), (2, krosti), (3, radler), (1, wasser)],
robin: [(1, mate), (4, krosti), (2, radler)],
melokomplott: [(5, mate), (13, sterni), (1, krosti), (1, radler)],
residudes: [(2, mate), (1, sterni), (15, krosti), (7, radler), (1, wasser)],
})
consumption(
day=3,
for_free=True,
drink_dict={
thure: [(1, mate), (4, sterni), (5, radler), (3, wasser)],
seth_family: [(1, mate), (2, sterni), (12, krosti), (1, wasser)],
andrew: [(3, sterni), (2, krosti), (3, radler), (1, wasser)],
robin: [(1, mate), (4, krosti), (2, radler)],
melokomplott: [(5, mate), (13, sterni), (1, krosti), (1, radler)],
residudes: [(2, mate), (1, sterni), (15, krosti), (7, radler), (1, wasser)],
},
)
# --------------- ADMIN STUFF ---------------
+94 -76
View File
@@ -35,16 +35,14 @@ def payment(purpose, day, month, amount):
def consumption(day: int, for_free: bool, drink_dict: Dict[User, List[Tuple[int, Drink]]]):
for user, drink_list in drink_dict.items():
for amount, drink in drink_list:
Consumption.objects.create(
user=user, drink=drink, amount=amount, day=day, for_free=for_free)
Consumption.objects.create(user=user, drink=drink, amount=amount, day=day, for_free=for_free)
class Command(BaseCommand):
@transaction.atomic()
def handle(self, *args, **options):
if any(model.objects.exists() for model in [Donation, Payment, Drink, Consumption]):
raise CommandError(
"clear all donation, payment, drink and consumption objects before running this command")
raise CommandError("clear all donation, payment, drink and consumption objects before running this command")
# --------------- PEOPLE ---------------
@@ -232,86 +230,106 @@ class Command(BaseCommand):
# --------------- THURSDAY ---------------
consumption(day=1, for_free=False, drink_dict={
enni: [(2, wasser), (9, sterni)],
robert: [(2, wasser), (2, freiberger), (1, spezi), (2, mate)],
josi: [(5, sterni), (1, radler)],
tobi: [(5, sterni), (1, freiberger), (2, mate)],
annemarie: [(1, wasser), (4, sterni), (1, radler)],
sandra: [(1, wasser), (3, sterni), (1, spezi), (1, mate)],
flo: [(2, wasser), (5, sterni), (1, mate), (1, helles)],
})
consumption(
day=1,
for_free=False,
drink_dict={
enni: [(2, wasser), (9, sterni)],
robert: [(2, wasser), (2, freiberger), (1, spezi), (2, mate)],
josi: [(5, sterni), (1, radler)],
tobi: [(5, sterni), (1, freiberger), (2, mate)],
annemarie: [(1, wasser), (4, sterni), (1, radler)],
sandra: [(1, wasser), (3, sterni), (1, spezi), (1, mate)],
flo: [(2, wasser), (5, sterni), (1, mate), (1, helles)],
},
)
# --------------- FRIDAY ---------------
consumption(day=2, for_free=False, drink_dict={
tobi: [(2, wasser), (9, sterni), (2, freiberger)],
annemarie: [(1, wasser), (5, sterni), (2, mate), (2, radler), (2, buddi), (3, sekt)],
sandra: [(1, freiberger), (1, buddi), (1, spezi), (2, mate), (1, radler), (2, sekt)],
robert: [(2, wasser), (1, freiberger), (1, buddi), (1, spezi)],
josi: [(2, wasser), (6, sterni), (1, freiberger), (2, radler)],
enni: [(2, wasser), (10, sterni), (1, spezi)],
steven: [(1, sterni), (1, krosti), (1, radler), (5, helles)],
marten: [(9, krosti)],
thure: [(4, sterni)],
jona: [(2, freiberger), (10, krosti)],
benni: [(5, krosti), (1, helles)],
katha: [(1, krosti), (1, mate)],
diana: [(5, sterni), (1, radler)],
katz: [(3, krosti), (1, buddi)],
alexius: [(8, sterni)],
pauline: [(5, sterni), (1, radler)],
herald: [(1, wasser), (2, sterni), (1, freiberger)],
arthur: [(6, sterni), (1, radler)],
matze: [(1, sterni), (1, freiberger)],
dennis: [(1, sterni), (2, krosti)],
marvin: [(3, sterni), (1, krosti), (1, mate)],
simon: [(1, sterni)],
})
consumption(
day=2,
for_free=False,
drink_dict={
tobi: [(2, wasser), (9, sterni), (2, freiberger)],
annemarie: [(1, wasser), (5, sterni), (2, mate), (2, radler), (2, buddi), (3, sekt)],
sandra: [(1, freiberger), (1, buddi), (1, spezi), (2, mate), (1, radler), (2, sekt)],
robert: [(2, wasser), (1, freiberger), (1, buddi), (1, spezi)],
josi: [(2, wasser), (6, sterni), (1, freiberger), (2, radler)],
enni: [(2, wasser), (10, sterni), (1, spezi)],
steven: [(1, sterni), (1, krosti), (1, radler), (5, helles)],
marten: [(9, krosti)],
thure: [(4, sterni)],
jona: [(2, freiberger), (10, krosti)],
benni: [(5, krosti), (1, helles)],
katha: [(1, krosti), (1, mate)],
diana: [(5, sterni), (1, radler)],
katz: [(3, krosti), (1, buddi)],
alexius: [(8, sterni)],
pauline: [(5, sterni), (1, radler)],
herald: [(1, wasser), (2, sterni), (1, freiberger)],
arthur: [(6, sterni), (1, radler)],
matze: [(1, sterni), (1, freiberger)],
dennis: [(1, sterni), (2, krosti)],
marvin: [(3, sterni), (1, krosti), (1, mate)],
simon: [(1, sterni)],
},
)
consumption(day=2, for_free=True, drink_dict={
flo: [(2, wasser), (3, sterni), (1, freiberger), (3, helles)],
casi: [(6, sterni)],
sepp: [(6, sterni)],
ohli: [(4, sterni)],
marius: [(1, radler)],
anonym: [(10, sterni), (10, krosti), (2, radler), (4, helles), (1, sekt)]
})
consumption(
day=2,
for_free=True,
drink_dict={
flo: [(2, wasser), (3, sterni), (1, freiberger), (3, helles)],
casi: [(6, sterni)],
sepp: [(6, sterni)],
ohli: [(4, sterni)],
marius: [(1, radler)],
anonym: [(10, sterni), (10, krosti), (2, radler), (4, helles), (1, sekt)],
},
)
# --------------- SATURDAY ---------------
consumption(day=3, for_free=False, drink_dict={
herald: [(1, sterni), (2, freiberger), (2, radler), (1, buddi), (5, spezi), (2, wasser)],
thure: [(6, sterni), (1, krosti), (1, radler), (2, spezi)],
sandra: [(6, sterni), (1, freiberger), (2, radler), (1, mate), (1, cola), (1, sekt)],
marvin: [(1, sterni), (1, mate)],
simon: [(10, sterni), (1, radler), (1, mate)],
jona: [(6, sterni), (4, krosti)],
robert: [(1, sterni), (1, freiberger), (1, buddi), (2, mate), (2, spezi), (3, wasser)],
steven: [(5, helles), (1, sterni), (2, radler), (1, mate)],
flo: [(4, helles), (1, freiberger), (1, buddi), (2, mate)],
matze: [(4, sterni), (2, radler), (3, buddi), (7, spezi)],
alexius: [(2, helles), (3, sterni), (1, radler), (1, cola)],
josi: [(5, sterni), (1, radler), (2, mate), (2, wasser), (1, sekt)],
benni: [(1, helles), (2, krosti), (2, radler), (1, wasser)],
ohli: [(1, helles), (3, sterni), (2, krosti), (1, radler), (1, buddi), (1, mate)],
arthur: [(3, sterni), (1, krosti), (1, radler), (1, mate), (3, spezi), (2, sekt)],
pauline: [(2, sterni), (2, radler), (1, mate), (1, cola)],
enni: [(9, sterni), (1, spezi), (2, wasser), (1, sekt)],
annemarie: [(5, sterni), (4, radler), (2, buddi), (1, mate), (1, wasser), (2, sekt)],
tobi: [(3, sterni), (1, radler), (1, mate), (1, wasser)],
marten: [(4, helles), (1, krosti)],
lukas: [(4, sterni), (1, spezi)],
lilly: [(5, sterni), (1, mate)],
andrea: [(1, buddi)],
lena: [(1, sterni)],
anonym: [(2, helles), (3, sterni), (5, krosti), (2, radler), (1, cola), (2, sekt)]
})
consumption(
day=3,
for_free=False,
drink_dict={
herald: [(1, sterni), (2, freiberger), (2, radler), (1, buddi), (5, spezi), (2, wasser)],
thure: [(6, sterni), (1, krosti), (1, radler), (2, spezi)],
sandra: [(6, sterni), (1, freiberger), (2, radler), (1, mate), (1, cola), (1, sekt)],
marvin: [(1, sterni), (1, mate)],
simon: [(10, sterni), (1, radler), (1, mate)],
jona: [(6, sterni), (4, krosti)],
robert: [(1, sterni), (1, freiberger), (1, buddi), (2, mate), (2, spezi), (3, wasser)],
steven: [(5, helles), (1, sterni), (2, radler), (1, mate)],
flo: [(4, helles), (1, freiberger), (1, buddi), (2, mate)],
matze: [(4, sterni), (2, radler), (3, buddi), (7, spezi)],
alexius: [(2, helles), (3, sterni), (1, radler), (1, cola)],
josi: [(5, sterni), (1, radler), (2, mate), (2, wasser), (1, sekt)],
benni: [(1, helles), (2, krosti), (2, radler), (1, wasser)],
ohli: [(1, helles), (3, sterni), (2, krosti), (1, radler), (1, buddi), (1, mate)],
arthur: [(3, sterni), (1, krosti), (1, radler), (1, mate), (3, spezi), (2, sekt)],
pauline: [(2, sterni), (2, radler), (1, mate), (1, cola)],
enni: [(9, sterni), (1, spezi), (2, wasser), (1, sekt)],
annemarie: [(5, sterni), (4, radler), (2, buddi), (1, mate), (1, wasser), (2, sekt)],
tobi: [(3, sterni), (1, radler), (1, mate), (1, wasser)],
marten: [(4, helles), (1, krosti)],
lukas: [(4, sterni), (1, spezi)],
lilly: [(5, sterni), (1, mate)],
andrea: [(1, buddi)],
lena: [(1, sterni)],
anonym: [(2, helles), (3, sterni), (5, krosti), (2, radler), (1, cola), (2, sekt)],
},
)
consumption(day=3, for_free=True, drink_dict={
rockbert: [(8, krosti), (1, radler), (1, mate)],
anonym: [(8, sterni), (2, krosti), (2, mate), (1, cola)]
})
consumption(
day=3,
for_free=True,
drink_dict={
rockbert: [(8, krosti), (1, radler), (1, mate)],
anonym: [(8, sterni), (2, krosti), (2, mate), (1, cola)],
},
)
# --------------- ADMIN STUFF ---------------
+1 -1
View File
@@ -20,4 +20,4 @@ class Command(BaseCommand):
name = id_to_name[drink_dict["drink_id"]]
amount = drink_dict["amount"]
drink_list.append(f"{amount}x {name}")
print(f"{user.username.capitalize()}: {euro(to_pay)} ({", ".join(drink_list)})")
print(f"{user.username.capitalize()}: {euro(to_pay)} ({', '.join(drink_list)})")
+151 -56
View File
@@ -10,94 +10,189 @@ import gaehsnitz.models
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
("auth", "0012_alter_user_first_name_max_length"),
]
operations = [
migrations.CreateModel(
name='User',
name="User",
fields=[
('id', models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
("id", models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("password", models.CharField(max_length=128, verbose_name="password")),
("last_login", models.DateTimeField(blank=True, null=True, verbose_name="last login")),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={"unique": "A user with that username already exists."},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
verbose_name="username",
),
),
("first_name", models.CharField(blank=True, max_length=150, verbose_name="first name")),
("last_name", models.CharField(blank=True, max_length=150, verbose_name="last name")),
("email", models.EmailField(blank=True, max_length=254, verbose_name="email address")),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
("date_joined", models.DateTimeField(default=django.utils.timezone.now, verbose_name="date joined")),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.permission",
verbose_name="user permissions",
),
),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
"verbose_name": "user",
"verbose_name_plural": "users",
"abstract": False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
("objects", django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Drink',
name="Drink",
fields=[
('id', models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True)),
('crates_ordered', models.PositiveSmallIntegerField(help_text='just informational to see how good we planned, not the actual consumed/paid drinks')),
('crates_purchased', models.PositiveSmallIntegerField()),
('crates_returned', models.PositiveSmallIntegerField()),
('purchase_price_per_crate', gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
('deposit_per_crate', gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
('bottles_per_crate', models.PositiveSmallIntegerField()),
('bottle_size', models.FloatField()),
('sale_price_per_bottle', gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
("id", models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("name", models.CharField(max_length=32, unique=True)),
(
"crates_ordered",
models.PositiveSmallIntegerField(
help_text="just informational to see how good we planned, not the actual consumed/paid drinks"
),
),
("crates_purchased", models.PositiveSmallIntegerField()),
("crates_returned", models.PositiveSmallIntegerField()),
("purchase_price_per_crate", gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
("deposit_per_crate", gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
("bottles_per_crate", models.PositiveSmallIntegerField()),
("bottle_size", models.FloatField()),
("sale_price_per_bottle", gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
],
),
migrations.CreateModel(
name='Payment',
name="Payment",
fields=[
('id', models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('purpose', models.CharField(max_length=64)),
('date', models.DateField()),
('amount', gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
('from_user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='payments', related_query_name='payment', to=settings.AUTH_USER_MODEL)),
("id", models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("purpose", models.CharField(max_length=64)),
("date", models.DateField()),
("amount", gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
(
"from_user",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="payments",
related_query_name="payment",
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.CreateModel(
name='Payback',
name="Payback",
fields=[
('id', models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateField()),
('amount', gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
('note', models.CharField(blank=True, default='', max_length=64)),
('to_user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='paybacks', related_query_name='payback', to=settings.AUTH_USER_MODEL)),
("id", models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("date", models.DateField()),
("amount", gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
("note", models.CharField(blank=True, default="", max_length=64)),
(
"to_user",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="paybacks",
related_query_name="payback",
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.CreateModel(
name='Donation',
name="Donation",
fields=[
('id', models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateField()),
('amount', gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
('note', models.CharField(blank=True, default='', max_length=64)),
('from_user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='donations', related_query_name='donation', to=settings.AUTH_USER_MODEL)),
("id", models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("date", models.DateField()),
("amount", gaehsnitz.models.PriceField(decimal_places=2, max_digits=6)),
("note", models.CharField(blank=True, default="", max_length=64)),
(
"from_user",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="donations",
related_query_name="donation",
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.CreateModel(
name='Consumption',
name="Consumption",
fields=[
('id', models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('amount', models.PositiveSmallIntegerField()),
('day', models.PositiveSmallIntegerField(choices=[(1, 'Do'), (2, 'Fr'), (3, 'Sa')])),
('for_free', models.BooleanField(default=False)),
('drink', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consumption_list', related_query_name='consumption', to='gaehsnitz.drink')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consumption_list', related_query_name='consumption', to=settings.AUTH_USER_MODEL)),
("id", models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("amount", models.PositiveSmallIntegerField()),
("day", models.PositiveSmallIntegerField(choices=[(1, "Do"), (2, "Fr"), (3, "Sa")])),
("for_free", models.BooleanField(default=False)),
(
"drink",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="consumption_list",
related_query_name="consumption",
to="gaehsnitz.drink",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="consumption_list",
related_query_name="consumption",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]
@@ -4,26 +4,25 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gaehsnitz', '0001_initial'),
("gaehsnitz", "0001_initial"),
]
operations = [
migrations.RemoveField(
model_name='donation',
name='from_user',
model_name="donation",
name="from_user",
),
migrations.RemoveField(
model_name='payment',
name='from_user',
model_name="payment",
name="from_user",
),
migrations.AlterField(
model_name='consumption',
name='day',
field=models.PositiveSmallIntegerField(choices=[(1, 'Do'), (2, 'Fr'), (3, 'Sa'), (4, 'So')]),
model_name="consumption",
name="day",
field=models.PositiveSmallIntegerField(choices=[(1, "Do"), (2, "Fr"), (3, "Sa"), (4, "So")]),
),
migrations.DeleteModel(
name='Payback',
name="Payback",
),
]
+7 -10
View File
@@ -4,14 +4,12 @@ from django.db.models import Sum, F
class PriceField(models.DecimalField):
def __init__(self, verbose_name=None, name=None, **kwargs):
kwargs.update({"max_digits": 6, "decimal_places": 2})
super().__init__(verbose_name, name, **kwargs)
class User(AbstractUser):
@property
def paid_drinks(self):
return self.consumption_list.filter(for_free=False)
@@ -22,9 +20,9 @@ class User(AbstractUser):
@property
def consumed_drinks_price(self):
query = self.paid_drinks \
.annotate(cost=F("amount") * F("drink__sale_price_per_bottle")) \
.aggregate(sum=Sum("cost"))
query = self.paid_drinks.annotate(cost=F("amount") * F("drink__sale_price_per_bottle")).aggregate(
sum=Sum("cost")
)
return query["sum"] or 0
@@ -45,7 +43,6 @@ class Payment(models.Model):
amount = PriceField()
class Drink(models.Model):
name = models.CharField(max_length=32, unique=True)
crates_ordered = models.PositiveSmallIntegerField(
@@ -127,11 +124,11 @@ class Drink(models.Model):
class Consumption(models.Model):
user = models.ForeignKey(
to=User, on_delete=models.CASCADE,
related_name="consumption_list", related_query_name="consumption")
to=User, on_delete=models.CASCADE, related_name="consumption_list", related_query_name="consumption"
)
drink = models.ForeignKey(
to=Drink, on_delete=models.CASCADE,
related_name="consumption_list", related_query_name="consumption")
to=Drink, on_delete=models.CASCADE, related_name="consumption_list", related_query_name="consumption"
)
amount = models.PositiveSmallIntegerField()
day = models.PositiveSmallIntegerField(choices=[(1, "Do"), (2, "Fr"), (3, "Sa"), (4, "So")])
for_free = models.BooleanField(default=False)
+28 -13
View File
@@ -53,21 +53,21 @@ body {
#title {
margin-top: 24px;
text-align: center;
color: #CCEE66;
color: #FFCC77;
font-weight: bold;
}
h1 {
margin-bottom: 10px;
font-size: 1.6rem;
color: #99EE33;
text-shadow: 0 0 16px #669933;
color: #EE9933;
text-shadow: 0 0 16px #CC6611;
}
#navi {
padding: 8px 0;
text-align: center;
color: #446622;
color: #885522;
}
#navi a {
@@ -77,7 +77,7 @@ h1 {
a {
text-decoration: none;
color: #99EE33;
color: #EE9933;
transition: color 100ms;
}
@@ -103,7 +103,7 @@ h2 {
margin-bottom: 14px;
font-size: 1.3rem;
font-weight: normal;
color: #99EE33;
color: #EE9933;
}
h3 {
@@ -111,7 +111,7 @@ h3 {
margin-bottom: 8px;
font-size: 1.15rem;
font-weight: normal;
color: #CCEE66;
color: #FFCC77;
}
p, ul {
@@ -131,15 +131,15 @@ table {
}
thead {
color: #CCEE66;
color: #FFCC77;
}
.odd-row {
background-color: rgba(40, 60, 20, 0.4);
background-color: rgba(80, 40, 10, 0.4);
}
.even-row {
background-color: rgba(40, 60, 20, 0.1);
background-color: rgba(80, 40, 10, 0.1);
}
td {
@@ -150,7 +150,7 @@ td {
hr {
margin-top: 24px;
margin-bottom: 24px;
border: 3px solid #446622;
border: 3px solid #885522;
border-radius: 3px;
}
@@ -191,7 +191,7 @@ hr {
margin-top: 12px;
margin-bottom: 12px;
border: 2px solid;
border-image: linear-gradient(to right, rgb(153, 238, 51) 0%, rgba(238, 153, 51, 0) 100%) 1;
border-image: linear-gradient(to right, rgb(238, 153, 51) 0%, rgba(238, 102, 34, 0) 100%) 1;
overflow: hidden;
}
@@ -200,7 +200,7 @@ hr {
max-width: 160px;
max-height: 90px;
z-index: -1;
box-shadow: 0 0 30px #446622;
box-shadow: 0 0 30px #885522;
}
.bandbox p {
@@ -249,3 +249,18 @@ hr {
.marked {
color: #CC66EE;
}
#footer {
margin-top: 32px;
padding-bottom: 32px;
border-bottom: 1px solid transparent;
}
/* archive pages: neutral blue-grey color scheme (content only, nav/title stay amber) */
.archive #content h2 { color: #D8DEF0; }
.archive #content h3 { color: #B8C0D8; }
.archive #content a { color: #B8C0D8; }
.archive #content thead { color: #B8C0D8; }
.archive #content .odd-row { background-color: rgba(180, 200, 255, 0.07); }
.archive #content .even-row { background-color: rgba(180, 200, 255, 0.02); }
.archive #content hr { border-color: #505870; }
@@ -0,0 +1,255 @@
{% extends "gaehsnitz/base.html" %}
{% block body_class %}archive{% endblock %}
{% block content %}
<h2>Archiv 2022</h2>
<p>25. - 28. August 2022</p>
<hr>
<h2>News</h2>
<h3>11.09. - Aftermath</h3>
<p>
Tja Leute, wie das immer so ist: lang geplant, kurz gefeiert... aber es war wieder absolut Klasse! Die bunte
Band-Mischung hat richtig gefetzt, die Versorgung hat der hohen Trichterfrequenz bei weitem standgehalten, aber
vor allem war mal wieder ein ganzer Haufen lieber Leute am Start,
<span class="accent">Danke dafür! ❤</span>
</p>
<h3>15.08. - TL;DR</h3>
<p>
In anderthalb Wochen ist es so weit, deshalb hier kurz das Wichtigste zusammengefasst:
</p>
<ul>
<li>Checkt die Anreise und bildet Fahrgemeinschaften.</li>
<li>Bringt gern Leute mit, aber fragt uns bitte vorher. Außerdem nicht im Internet posten - die Veranstaltung ist privat.</li>
<li>Bitte helft uns mit eurer Eintrittsspende und noch besser vorab mit einem Suff-Kredit. ❤</li>
<li>Suff aller Art gibt's genug und zu fairen Preisen.</li>
<li>Das Essen könnte knapp werden. Bitte bringt eine Kleinigkeit mit (Aufstriche, Salate, Käse etc.).</li>
<li>Draußen gibt es kein Trinkwasser - bringt Wasserkanister mit.</li>
</ul>
<h3>17.07. - .. es wird!</h3>
<p>
Wir haben uns dieses Wochenende noch einmal ins Zeug gelegt: einen Drehstrom-Anschluss verkabelt, die Bar neu
lackiert, den Drum-Riser gebaut, die Laube aufgeräumt und mal wieder überall gemäht.
</p>
<h3>27.05. - Himmelfahrtsaktion</h3>
<p>Am Wochenende nach Himmelfahrt haben wir schonmal gaaanz viel geschafft:</p>
<ul>
<li>Rasen gemäht und einige Büsche verschnitten</li>
<li>die Bar stabilisiert</li>
<li>die Bühnenfläche vermessen, mit Platten begrenzt und geebnet</li>
<li>die Hauptfläche weiter begradigt</li>
<li>sämtliches Holz am Grundstücksrand gestapelt</li>
</ul>
<hr>
<h2>Programm</h2>
<ul>
<li>Donnerstag 25.: Aufbau</li>
<li>Freitag 26.: Quast, Direct Juice</li>
<li>Samstag 27.: Melo-Komplott, The Residudes, RATs</li>
<li>Sonntag 28.: Abbau</li>
</ul>
<hr>
<h2>Von A bis Z</h2>
<p>
Wie letztes Jahr schon werden wir womöglich demnächst mal auswerten, wie die Dinge im Detail so gelaufen sind.
Dann wird hier alles kommentiert, damit wir uns das bis nächstes Jahr merken können. ;)
</p>
<h3 id="address">Adresse &amp; Anfahrt</h3>
<p>
Die Sause findet im Garten auf dem Grundstück von Tobis Eltern statt.
</p>
<p>
Adresse: Gähsnitzer Ring 9, 04618 Nobitz<br>
Koordinaten: 50.9070, 12.5465
</p>
<p>
Bekanntlich kann man ja im August noch für 9,-€ die Welt bereisen, daher empfiehlt sich die gemeinsame Anreise
<span class="accent">mit dem Zug</span>. Die S5X fährt stündlich um :40 von Leipzig Hbf und kommt um :25 in
Gößnitz an. Von dort sind es noch etwa 11km.
</p>
<h3 id="event">Art der Veranstaltung</h3>
<p>
Das ganze ist immer noch eine private Gartenparty, keine angemeldete Veranstaltung! Das bringt folgende Regeln
mit sich:
</p>
<ul>
<li>Bitte macht <span class="accent">keine öffentliche Werbung</span>, vor allem nicht im Internet.</li>
<li>Ihr könnt Freund*innen mitbringen, aber bitte fragt uns vorher mal kurz.</li>
<li>Achtet auf das Wohl der Anwohner*innen.</li>
<li>Live-Mucke sollte bis 22:00 durch sein. Danach können wir immer noch Konservenmucke hören, aber am besten nur auf 70% Lautstärke. ;)</li>
</ul>
<h3 id="food">Essen</h3>
<p>
Hauptmahlzeiten: Am Donnerstag werden wir wohl den Grill anhauen. Am Freitag und Samstag wird es jeweils eine
vegane Hauptmahlzeit aus dem großen Feuertopf geben.
</p>
<p>
Rundherum bitten wir euch, euch <span class="accent">selbst etwas zu essen mitzubringen</span> - Aufstriche,
Salate, Käse etc. in verschließbaren Behältern. Wir besorgen Brot/Brötchen und einen Grundvorrat.
</p>
<h3 id="drinks">Getränke &amp; Bar</h3>
<p>
Ein lokaler Getränkehändler bringt uns 'nen LKW voll Suff vorbei - es gibt Bier, Radler, Wasser, Mate und Cola.
Alles wird in Flaschen verkauft, seid deshalb bitte besonders vorsichtig, dass nichts zu Bruch geht!
</p>
<h3>Mucke &amp; Playlists</h3>
<p>
DJ Hymr wird einen Haufen Mucke bereithalten. Darüber hinaus gibt es Klinkenparty, allerdings streng limitiert
von den Geschmäckern der Veranstalter. :P
</p>
<h3>Parken &amp; Zelten</h3>
<p>
Der Großteil des Gartens (hinter der Bühne) dient als Zeltplatz. Es gibt einige Parkplätze rund um das
Grundstück und die Garage.
</p>
<h3 id="sanitary">Sanitär</h3>
<p>
<span class="accent">Es gibt kein Wasser auf dem Gelände!</span> Wenn ihr die Möglichkeit habt, bringt bitte
größtmögliche <span class="accent">Wasserkanister</span> (auch leer) mit. Es wird Dixi-Toiletten mit
Desinfektionsmittel und einem mobilen Waschbecken geben.
</p>
<h3>Wetter</h3>
<p>
Wir haben viele Pavillons, um auch bei Regen noch einigermaßen gute Laune zu wahren. Haltet Abstand mit Feuer
zur Vegetation und werft keine Kippen in die Gegend!
</p>
<hr>
<h2>Bühne &amp; Technik</h2>
<h3>Backline</h3>
<ul>
<li>Bassbox: Markbass 4x10", 4 Ohm, Speakon</li>
<li>Gitarrenbox: JetCity 2x12", 8 Ohm, Klinke</li>
<li>Drums: Pearl, Bassdrum, 3 Toms, Stative für Snare, HiHat, Crash, Ride</li>
<li>(Bass-Amp: Markbass Little Mark Tube 800 darf mitgenutzt werden)</li>
<li>(Gitarrenkombo: Blackstar HT-5 darf mitbenutzt werden)</li>
</ul>
<h3>Mikrofonierung</h3>
<ul>
<li>3 Gesangsmikros: SM58, PG58 und noch 'n billiges</li>
<li>3 Amp/Instrumenten-Mikros (Bass sowieso lieber via DI)</li>
<li>Drum-Mikros: t.bone Beta BD 500 und ein Set für alles andere</li>
<li>1 DI-Box</li>
<li>6 große Mikro-Stative, 3 kleine Mikro-Stative</li>
</ul>
<h3>Monitoring</h3>
<ul>
<li>1 Aktivbox neben den Drums</li>
<li>2 Front-Monitore (RATs)</li>
</ul>
<h3>PA</h3>
<ul>
<li>Mischpult &amp; Stagebox: Behringer X-Air 18</li>
<li>Beschallung: 2 aktive Subwoofer, 2 passive Hochtöner + Amp, Stative</li>
</ul>
<hr>
<h2>Finanzen</h2>
<p>
Da eine offene Kommunikation irgendwie zu dem ganzen unkommerziellen DIY-Gedöhns dazugehört, findet ihr hier
ganz transparent eine Übersicht, von wo nach wo eigentlich wie viel Kohle geflossen ist.
Nur keine Klarnamen. ;)
</p>
<h3>Zusammenfassung</h3>
<table>
<tr class="odd-row">
<td>Summe aller Spenden/Zahlungen</td>
<td>1.130 €</td>
</tr>
<tr class="even-row">
<td>Summe aller Ausgaben</td>
<td>1.250 €</td>
</tr>
<tr class="odd-row">
<td>Stand</td>
<td class="accent">-120 €</td>
</tr>
</table>
<h3>Ausgaben</h3>
<table>
<thead>
<tr class="odd-row">
<td>Zweck</td>
<td>Betrag</td>
<td>Datum</td>
</tr>
</thead>
<tr class="even-row">
<td>Baumarkt/Elektrik</td>
<td>70 €</td>
<td>16.07.</td>
</tr>
<tr class="odd-row">
<td>Baumarkt/Elektrik</td>
<td>27 €</td>
<td>18.07.</td>
</tr>
<tr class="even-row">
<td>Dixis</td>
<td>328 €</td>
<td>08.08.</td>
</tr>
<tr class="odd-row">
<td>Getränke/Anzahlung</td>
<td>400 €</td>
<td>22.08.</td>
</tr>
<tr class="even-row">
<td>Supermarkt/Essen</td>
<td>193 €</td>
<td>25.08.</td>
</tr>
<tr class="odd-row">
<td>Getränke/Abrechnung</td>
<td>122 €</td>
<td>01.09.</td>
</tr>
<tr class="even-row">
<td>Bands</td>
<td>110 €</td>
<td>-</td>
</tr>
</table>
<p>
Details zu den Spenden und Rückzahlungen an die Leute, die die Ausgaben geleistet haben,
lassen wir hier erstmal weg. Wer's ganz genau wissen will, kann ja fragen.
</p>
<p>
Nicht aufgelistet sind kurzfristige Dinge für die Vorbereitungsaktionen, also z.B. Suff und Sprit, den wir für
die Arbeitseinsätze gekauft und auch direkt vernichtet haben. Danke an dieser Stelle nochmal allen für die
jeweiligen Einkäufe und die unbezahlbare Arbeitskraft!
</p>
{% endblock %}
@@ -0,0 +1,273 @@
{% extends "gaehsnitz/base.html" %}
{% load static %}
{% load money %}
{% block body_class %}archive{% endblock %}
{% block content %}
<h2>Archiv 2024</h2>
<p>06. - 09. Juni 2024</p>
<hr>
<h2>News</h2>
<h3>06.05. - Hochoffizielle Einladung</h3>
<p>
Der Plan für Gähsnitz dieses Jahr steht und zur Motivation gibt's diesmal auch 'n digitales Plakat. 🍾
</p>
<a href="{% static 'gaehsnitz/plakat-2024.jpg' %}">
<img id="flyer" src="{% static 'gaehsnitz/plakat-2024-small.jpg' %}" alt="Plakat">
</a>
<p>
Fühlt euch alle eingeladen, am 6., 7., spätestens aber am 8. Juni bei uns im Garten vorbeizuschneien. Es gibt
bunt gemischte Live-Musik, Getränke für'n schmalen Taler, echte Landluft und was sonst noch alles auf dem Bild
zu finden ist.
</p>
<p>
Mehr Details gibt's nochmal 1-2 Wochen vorher - bis dahin einfach den Termin freihalten, Urlaub nehmen oder
kündigen, und am besten auch schonmal üben, wie man ganz schnell Pavillons aufbaut und Wurfzelte wieder in ihre
Verpackung kriegt.
</p>
<p>
Bringt gern noch mehr liebe Leute mit, aber bitte nich bei MySpace posten oder Plakate aufhängen - ist immer
noch 'ne Privatveranstaltung. ;)
</p>
<h3>04.04. - Der Winterschlaf ist vorbei</h3>
<p>
Der Termin für unsere diesjährige Gartensause steht ja schon seit letztem Jahr fest:
<span class="accent">06. - 09. Juni</span>. Sogar die Dixis sind schon vorbestellt! Den größten Fokus (und die
meiste Live-Mucke) wollen wir dieses Mal auf Samstag (08.06.) legen, aber mehr dazu später.
</p>
<p>
Über Ostern waren haben wir uns mal das Gelände angeschaut und uns gefreut, dass sich in anderthalb Jahren gar
nicht mal so viel verändert hat - sogar das Drum-Podest ist noch nutzbar. Trotzdem gibt's natürlich alle Hände
voll zu tun, um den Garten wieder festivaltauglich zu machen und zu konservieren.
</p>
<p>
Wir wollen über <span class="accent">Himmelfahrt</span> (09. - 12.05.) nochmal hinfahren und könnten dafür auch
so viele helfende Hände wie möglich gebrauchen. Wer also Bock auf Handarbeit, kühle Getränke und Feuermachen in
der Pampa hat, bitte melden! :)
</p>
<p>
Nun zur To-do-Liste: zum einen gibt's viel zu <span class="accent">gärtnern</span>:
</p>
<ul>
<li>Rasen mähen</li>
<li>"Palisade" befestigen, damit sie nicht zu breit wird</li>
<li>Efeu vom Boden entfernen / Fläche neben dem Schuppen wieder nutzbar machen</li>
<li>Bäume, Büsche und Hecken auf dem Gelände verschneiden (auch überm Dach der Laube)</li>
<li>Bäume und Büsche an den Grundstücksgrenzen verschneiden (vor allem oben an der Ecke)</li>
<li>Todholz einsammeln und die Palisade erweitern / Feuerholz separat sammeln</li>
<li>Müll/Schrott sammeln</li>
<li>neuen Rasen sähen</li>
</ul>
<p>
Zum anderen gibt es Folgendes zu <span class="accent">bauen</span>:
</p>
<ul>
<li>
Bar: neue OSB-Platte drauf schrauben, nochmal lackieren<br>
Maße: 310 lang, 63 breit
</li>
<li>
Erde auf der Bühne aufschütten und neu ebnen, womöglich noch ein paar Steinplatten dazulegen
</li>
<li>
Treppe zur Laube bzw. zur "Hochebene" bauen (Erde kann für Bühne genutzt werden)
</li>
<li>
Drum-Podest erneuern: marode Stellen mit Ziegelsteinen befestigen, OSB-Platten drauf schrauben,
lackieren<br>
Maße: 240 breit, 160 lang
</li>
<li>
lose Paletten streichen
</li>
<li>
<del>Plumpsklo: Wände putzen, neuen Boden bauen, neue Sitzbank bauen, Brille besorgen</del>
<br>
Maße Sitzbank: 70 breit, 50 tief
</li>
</ul>
<p>
Hier ist der <span class="accent">Einkaufszettel</span> dafür:
</p>
<ul>
<li>Rasensamen, z.B. 5 kg für 200 m² - 30 €</li>
<li>Bar: OSB-Platte, z.B. 250x125 cm längs halbiert, 18 mm stark, 37 €</li>
<li>Drum-Podest: OSB-Verlegeplatten, z.b. 4x 205x67 cm, 25 mm stark, 80 €</li>
<li>Holzfarbe: z.B. Wetterschutzfarbe schwedenrot 2,5 l (reicht für Bar und Podest), 38 €</li>
<li>Holzlasur: z.B. 10 l Kanister, 10 €</li>
<li>
<del>Plumpsklo</del>
</li>
</ul>
<p>&rarr; ca. 200 €</p>
<p>
Und weil's so schön ist, hier noch ein paar Impressionen, Stand 30.03.:
</p>
<div class="image-list">
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-eingang-auszen.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-eingang-innen.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/bar-fern.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/bar-nah.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/buehne-bar-palisade.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/buehne.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-von-unten.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-von-vorn.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-von-oben.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-dach.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/haus-zeltplatz.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-eingang.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/haus-buesche.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/haus-feuerholz.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/unten-gewaechshaus.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/unten-wiese.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/unten-rand.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/schuppen.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-efeu.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-pissecke.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-waeldchen.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-zaun.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-portal.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/grosze-tanne.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-kirschen.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-hecke.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-oben.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-spaghetti.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-rand.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/plumpsklo.jpg' %}" alt=""></div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/plumpsklo-boden.jpg' %}" alt=""></div>
</div>
<hr>
<h2>Programm</h2>
<ul>
<li>Donnerstag 06.: ganz viel Aufbau</li>
<li>Freitag 07.: Warm-Up</li>
<li>Samstag 08.: ganz viel Live-Mucke</li>
<li>Sonntag 09.: ganz viel Abbau</li>
</ul>
<hr>
<h2>Bühne &amp; Technik</h2>
<p>zur Info für Künstler*innen und als Packliste für uns ;)</p>
<h3>Backline</h3>
<ul>
<li>
Drums:<br>
(Josi) Bassdrum, 2 Toms, Floor-Tom, Hocker, Stative für Snare, HiHat, Crash und Ride<br>
(Josi) Snare (nur für Open Stage)<br>
(Flo) Iron Cobra 600 Double Bass Pedal (darf für alles mitbenutzt werden)<br>
(Tobi) HiHat, Crash, Ride (nur für Open Stage)
</li>
<li>Bassbox: Markbass 4x10", 4 Ohm, Speakon</li>
<li>(Bass-Topteil: Markbass Little Mark Tube 800 darf mitbenutzt werden)</li>
<li>Gitarrenbox: Palmer 2x12", 8 Ohm, Klinke</li>
<li>(Gitarrenkombo: Blackstar HT-5 darf mitbenutzt werden)</li>
</ul>
<h3>Mikrofonierung</h3>
<ul>
<li>Kick: t.bone Beta 500</li>
<li>Snare: SM57</li>
<li>Toms: 3x Audix f2</li>
<li>Overheads: 2x Rode M5</li>
<li>Amps: 3x Superlux Grenzfläche</li>
<li>DI: 1x Behringer DI-Box (Mono)</li>
<li>Gesang: 1x Beta 58, 1x SM58 (Sepp), 1x Superlux</li>
<li>Stative: mal Inventur machen ...</li>
</ul>
<h3>Monitoring</h3>
<ul>
<li>3 Boxen angefragt mit der PA, noch in Klärung ...</li>
</ul>
<h3>PA</h3>
<ul>
<li>Mischpult &amp; Stagebox: Behringer X-Air 18</li>
<li>Beschallung: HK-Audio Pro, 2 18"-Subs, 2 Tops, aktiv</li>
</ul>
<h3>Beleuchtung</h3>
<ul>
<li>2x Bars mit jeweils 4 LED-Spots</li>
<li>Superfly</li>
<li>DMX-Steuerung über Laptop möglich</li>
</ul>
<h3>Kabel</h3>
<ul>
<li>24x XLR (16 Channels, 3 Monitore, 4 PA, 1 Reserve)</li>
<li>2x XLR-Male ↔ Klinke</li>
<li>13x Kaltgeräte-Stecker (Mixer, Markbass, Blackstar, 3 Monitore, 4 PA, 1 Lampe, 1 Reserve)</li>
<li>2x Kaltgeräte-Verlängerung (zwischen Lampen)</li>
<li>4x DMX (3 Lampen, 1 Reserve)</li>
<li>...</li>
</ul>
<hr>
<h2>Finanzen</h2>
<p>
Da eine offene Kommunikation irgendwie zu dem ganzen unkommerziellen DIY-Gedöhns dazugehört, findet ihr hier
ganz transparent eine Übersicht, von wo nach wo eigentlich wie viel Kohle geflossen ist.
Nur keine Klarnamen. ;)
</p>
<h3>Zusammenfassung</h3>
<table>
<tr class="odd-row">
<td>Summe aller Spenden/Zahlungen</td>
<td>{{ total_donations|euro }}</td>
</tr>
<tr class="even-row-row">
<td>Summe aller Ausgaben</td>
<td>{{ total_payments|euro }}</td>
</tr>
<tr class="odd-row">
<td>Stand</td>
<td class="accent">{{ total_balance|euro }}</td>
</tr>
</table>
<h3>Ausgaben</h3>
<table>
<thead>
<tr class="odd-row">
<td>Zweck</td>
<td>Betrag</td>
<td>Datum</td>
</tr>
</thead>
{% for payment in payments %}
<tr class="{% cycle 'even-row' 'odd-row' %}">
<td>{{ payment.purpose }}</td>
<td>{{ payment.amount|euro }}</td>
<td>{% if payment.date %}{{ payment.date|date:"d.m." }}{% else %}-{% endif %}</td>
</tr>
{% endfor %}
</table>
<p>
Details zu den Spenden und Rückzahlungen an die Leute, die die Ausgaben geleistet haben,
lassen wir hier erstmal weg. Wer's ganz genau wissen will, kann ja fragen.
</p>
<p>
Nicht aufgelistet sind kurzfristige Dinge für die Vorbereitungsaktionen, also z.B. Suff und Sprit, den wir für
die Arbeitseinsätze gekauft und auch direkt vernichtet haben. Danke an dieser Stelle nochmal allen für die
jeweiligen Einkäufe und die unbezahlbare Arbeitskraft!
</p>
{% endblock %}
-9
View File
@@ -1,9 +0,0 @@
{% extends "gaehsnitz/base.html" %}
{% load static %}
{% block content %}
<h2>&#128736; Alles noch in Planung</h2>
<p>Bald gibt's mehr Infos.</p>
{% endblock %}
+10 -10
View File
@@ -8,21 +8,15 @@
<title>Gähsnitz Open Air</title>
<link rel="stylesheet" type="text/css" href="{% static 'gaehsnitz/style.css' %}">
</head>
<body>
<body class="{% block body_class %}{% endblock %}">
<div id="title">
<h1>Gähsnitz Open Air 2024</h1>
~ Do 06. - So 09. Juni ~
<h1>Gähsnitz Open Air 2026</h1>
~ Do 11. - So 14. Juni ~
</div>
<div id="navi">
<a href="{% url 'gaehsnitz:news' %}">News</a>
|
<a href="{% url 'gaehsnitz:atoz' %}">A-Z</a>
|
<a href="{% url 'gaehsnitz:program' %}">Programm</a>
|
<a href="{% url 'gaehsnitz:finance' %}">Finanzen</a>
<a href="{% url 'gaehsnitz:news' %}">Festival</a>
|
<a href="{% url 'gaehsnitz:for-bands' %}">für Bands</a>
</div>
@@ -31,5 +25,11 @@
{% block content %}{% endblock %}
</div>
<div id="footer">
<a href="{% url 'gaehsnitz:archive-2022' %}">Archiv 2022</a>
|
<a href="{% url 'gaehsnitz:archive-2024' %}">Archiv 2024</a>
</div>
</body>
</html>
@@ -1,62 +0,0 @@
{% extends "gaehsnitz/base.html" %}
{% load money %}
{% block content %}
<h2>&#128736; Abwarten</h2>
<p>Auch hier wird noch geplant ...</p>
<h2>Details</h2>
<p>
Da eine offene Kommunikation irgendwie zu dem ganzen unkommerziellen DIY-Gedöhns dazugehört, findet ihr hier
ganz transparent eine Übersicht, von wo nach wo eigentlich wie viel Kohle geflossen ist.
Nur keine Klarnamen. ;)
</p>
<h3>Zusammenfassung</h3>
<table>
<tr class="odd-row">
<td>Summe aller Spenden/Zahlungen</td>
<td>{{ total_donations|euro }}</td>
</tr>
<tr class="even-row-row">
<td>Summe aller Ausgaben</td>
<td>{{ total_payments|euro }}</td>
</tr>
<tr class="odd-row">
<td>Stand</td>
<td class="accent">{{ total_balance|euro }}</td>
</tr>
</table>
<h3>Ausgaben</h3>
<table>
<thead>
<tr class="odd-row">
<td>Zweck</td>
<td>Betrag</td>
<td>Datum</td>
</tr>
</thead>
{% for payment in payments %}
<tr class="{% cycle 'even-row' 'odd-row' %}">
<td>{{ payment.purpose }}</td>
<td>{{ payment.amount|euro }}</td>
<td>{% if payment.date %}{{ payment.date|date:"d.m." }}{% else %}-{% endif %}</td>
</tr>
{% endfor %}
</table>
<p>
Details zu den Spenden und Rückzahlungen an die Leute, die die Ausgaben geleistet haben,
lassen wir hier erstmal weg. Wer's ganz genau wissen will, kann ja fragen.
</p>
<p>
Nicht aufgelistet sind kurzfristige Dinge für die Vorbereitungsaktionen, also z.B. Suff und Sprit, den wir für
die Arbeitseinsätze gekauft und auch direkt vernichtet haben. Danke an dieser Stelle nochmal allen für die
jeweiligen Einkäufe und die unbezahlbare Arbeitskraft!
</p>
{% endblock %}
+118 -142
View File
@@ -1,168 +1,144 @@
{% extends "gaehsnitz/base.html" %}
{% load static %}
{% load money %}
{% block content %}
<h2>06.05. - Hochoffizielle Einladung</h2>
<h2>Über uns</h2>
<p>
Der Plan für Gähsnitz dieses Jahr steht und zur Motivation gibt's diesmal auch 'n digitales Plakat. 🍾
</p>
<a href="{% static 'gaehsnitz/plakat-2024.jpg' %}">
<img id="flyer" src="{% static 'gaehsnitz/plakat-2024-small.jpg' %}" alt="Plakat">
</a>
<p>
Fühlt euch alle eingeladen, am 6., 7., spätestens aber am 8. Juni bei uns im Garten vorbeizuschneien. Es gibt
bunt gemischte Live-Musik, Getränke für'n schmalen Taler, echte Landluft und was sonst noch alles auf dem Bild
zu finden ist.
</p>
<p>
Mehr Details gibt's nochmal 1-2 Wochen vorher - bis dahin einfach den Termin freihalten, Urlaub nehmen oder
kündigen, und am besten auch schonmal üben, wie man ganz schnell Pavillons aufbaut und Wurfzelte wieder in ihre
Verpackung kriegt.
</p>
<p>
Bringt gern noch mehr liebe Leute mit, aber bitte nich bei MySpace posten oder Plakate aufhängen - ist immer
noch 'ne Privatveranstaltung. ;)
Angefangen hat das alles als Geburtstagsparty - irgendwann hat sich daraus eine kleine Gruppe geformt,
die sich ab und zu zusammensetzt und dieses winzige Festival plant. Kein Kommerz, kein großes Ding,
einfach ein paar Tage Musik, gute Leute und frische Luft im Garten.
</p>
<hr>
<h2>04.04. - Der Winterschlaf ist vorbei</h2>
<h2>Programm</h2>
<ul>
<li>Donnerstag 11.: Aufbau</li>
<li>Freitag 12.: Melokomplott, M&#xF8;rtel</li>
<li>Samstag 13.: Quast, Knast, Kotpiloten</li>
<li>Sonntag 14.: Abbau</li>
</ul>
<hr>
<h2>Von A bis Z</h2>
<p class="marked">kopiert von 2022 - muss noch angepasst werden</p>
<h3 id="address">Adresse &amp; Anfahrt</h3>
<p>
Der Termin für unsere diesjährige Gartensause steht ja schon seit letztem Jahr fest:
<span class="accent">06. - 09. Juni</span>. Sogar die Dixis sind schon vorbestellt! Den größten Fokus (und die
meiste Live-Mucke) wollen wir dieses Mal auf Samstag (08.06.) legen, aber mehr dazu später.
Die Sause findet im Garten auf dem Grundstück von Tobis Eltern statt.
</p>
<p>
Über Ostern waren haben wir uns mal das Gelände angeschaut und uns gefreut, dass sich in anderthalb Jahren gar
nicht mal so viel verändert hat - sogar das Drum-Podest ist noch nutzbar. Trotzdem gibt's natürlich alle Hände
voll zu tun, um den Garten wieder festivaltauglich zu machen und zu konservieren.
Adresse: Gähsnitzer Ring 9, 04618 Nobitz<br>
Koordinaten: 50.9070, 12.5465
</p>
<p>
Wir wollen über <span class="accent">Himmelfahrt</span> (09. - 12.05.) nochmal hinfahren und könnten dafür auch
so viele helfende Hände wie möglich gebrauchen. Wer also Bock auf Handarbeit, kühle Getränke und Feuermachen in
der Pampa hat, bitte melden! :)
Bekanntlich kann man ja im August noch für 9,-€ die Welt bereisen, daher empfiehlt sich die gemeinsame Anreise
<span class="accent">mit dem Zug</span>. Die S5X fährt stündlich um :40 von Leipzig Hbf und kommt um :25 in
Gößnitz an. Von dort sind es noch etwa 11km.
</p>
<h3 id="event">Art der Veranstaltung</h3>
<p>
Nun zur To-do-Liste: zum einen gibt's viel zu <span class="accent">gärtnern</span>:
Das ganze ist immer noch eine private Gartenparty, keine angemeldete Veranstaltung! Das bringt folgende Regeln
mit sich:
</p>
<ul>
<li>Rasen mähen</li>
<li>"Palisade" befestigen, damit sie nicht zu breit wird</li>
<li>Efeu vom Boden entfernen / Fläche neben dem Schuppen wieder nutzbar machen</li>
<li>Bäume, Büsche und Hecken auf dem Gelände verschneiden (auch überm Dach der Laube)</li>
<li>Bäume und Büsche an den Grundstücksgrenzen verschneiden (vor allem oben an der Ecke)</li>
<li>Todholz einsammeln und die Palisade erweitern / Feuerholz separat sammeln</li>
<li>Müll/Schrott sammeln</li>
<li>neuen Rasen sähen</li>
<li>Bitte macht <span class="accent">keine öffentliche Werbung</span>, vor allem nicht im Internet.</li>
<li>Ihr könnt Freund*innen mitbringen, aber bitte fragt uns vorher mal kurz.</li>
<li>Achtet auf das Wohl der Anwohner*innen.</li>
<li>Live-Mucke sollte bis 22:00 durch sein. Danach können wir immer noch Konservenmucke hören, aber am besten nur auf 70% Lautstärke. ;)</li>
</ul>
<h3 id="food">Essen</h3>
<p>
Zum anderen gibt es Folgendes zu <span class="accent">bauen</span>:
Hauptmahlzeiten: Am Donnerstag werden wir wohl den Grill anhauen. Am Freitag und Samstag wird es jeweils eine
vegane Hauptmahlzeit aus dem großen Feuertopf geben.
</p>
<ul>
<li>
Bar: neue OSB-Platte drauf schrauben, nochmal lackieren<br>
Maße: 310 lang, 63 breit
</li>
<li>
Erde auf der Bühne aufschütten und neu ebnen, womöglich noch ein paar Steinplatten dazulegen
</li>
<li>
Treppe zur Laube bzw. zur "Hochebene" bauen (Erde kann für Bühne genutzt werden)
</li>
<li>
Drum-Podest erneuern: marode Stellen mit Ziegelsteinen befestigen, OSB-Platten drauf schrauben,
lackieren<br>
Maße: 240 breit, 160 lang
</li>
<li>
lose Paletten streichen
</li>
<li>
<del>Plumpsklo: Wände putzen, neuen Boden bauen, neue Sitzbank bauen, Brille besorgen</del>
<br>
Maße Sitzbank: 70 breit, 50 tief
</li>
</ul>
<p>
Hier ist der <span class="accent">Einkaufszettel</span> dafür:
Rundherum bitten wir euch, euch <span class="accent">selbst etwas zu essen mitzubringen</span> - Aufstriche,
Salate, Käse etc. in verschließbaren Behältern. Wir besorgen Brot/Brötchen und einen Grundvorrat.
</p>
<ul>
<li>Rasensamen, z.B. 5 kg für 200 m² - 30 €</li>
<li>Bar: OSB-Platte, z.B. 250x125 cm längs halbiert, 18 mm stark, 37 €</li>
<li>Drum-Podest: OSB-Verlegeplatten, z.b. 4x 205x67 cm, 25 mm stark, 80 €</li>
<li>Holzfarbe: z.B. Wetterschutzfarbe schwedenrot 2,5 l (reicht für Bar und Podest), 38 €</li>
<li>Holzlasur: z.B. 10 l Kanister, 10 €</li>
<li>
<del>Plumpsklo</del>
</li>
</ul>
<p>&rarr; ca. 200 €</p>
<h3 id="drinks">Getränke &amp; Bar</h3>
<p>
Und weil's so schön ist, hier noch ein paar Impressionen, Stand 30.03.:
Ein lokaler Getränkehändler bringt uns 'nen LKW voll Suff vorbei - es gibt Bier, Radler, Wasser, Mate und Cola.
Alles wird in Flaschen verkauft, seid deshalb bitte besonders vorsichtig, dass nichts zu Bruch geht!
</p>
<div class="image-list">
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-eingang-auszen.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-eingang-innen.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/bar-fern.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/bar-nah.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/buehne-bar-palisade.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/buehne.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-von-unten.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-von-vorn.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-von-oben.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/laube-dach.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/haus-zeltplatz.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-eingang.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/haus-buesche.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/haus-feuerholz.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/unten-gewaechshaus.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/unten-wiese.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/unten-rand.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/schuppen.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-efeu.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-pissecke.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-waeldchen.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-zaun.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/rand-portal.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/grosze-tanne.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-kirschen.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-hecke.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/strasze-oben.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-spaghetti.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/feld-rand.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/plumpsklo.jpg' %}" alt="">
</div>
<div class="image-wrapper"><img src="{% static 'gaehsnitz/photos-2024-03-30/plumpsklo-boden.jpg' %}" alt="">
</div>
</div>
<h3>Parken &amp; Zelten</h3>
<p>
Der Großteil des Gartens (hinter der Bühne) dient als Zeltplatz. Es gibt einige Parkplätze rund um das
Grundstück und die Garage.
</p>
<h3 id="sanitary">Sanitär</h3>
<p>
<span class="accent">Es gibt kein Wasser auf dem Gelände!</span> Wenn ihr die Möglichkeit habt, bringt bitte
größtmögliche <span class="accent">Wasserkanister</span> (auch leer) mit. Es wird Dixi-Toiletten mit
Desinfektionsmittel und einem mobilen Waschbecken geben.
</p>
<h3>Wetter</h3>
<p>
Wir haben viele Pavillons, um auch bei Regen noch einigermaßen gute Laune zu wahren. Haltet Abstand mit Feuer
zur Vegetation und werft keine Kippen in die Gegend!
</p>
<hr>
<h2>Finanzen</h2>
<p>
Da eine offene Kommunikation irgendwie zu dem ganzen unkommerziellen DIY-Gedöhns dazugehört, findet ihr hier
ganz transparent eine Übersicht, von wo nach wo eigentlich wie viel Kohle geflossen ist.
Nur keine Klarnamen. ;)
</p>
<h3>Zusammenfassung</h3>
<table>
<tr class="odd-row">
<td>Summe aller Spenden/Zahlungen</td>
<td>{{ total_donations|euro }}</td>
</tr>
<tr class="even-row">
<td>Summe aller Ausgaben</td>
<td>{{ total_payments|euro }}</td>
</tr>
<tr class="odd-row">
<td>Stand</td>
<td class="accent">{{ total_balance|euro }}</td>
</tr>
</table>
<h3>Ausgaben</h3>
<table>
<thead>
<tr class="odd-row">
<td>Zweck</td>
<td>Betrag</td>
<td>Datum</td>
</tr>
</thead>
{% for payment in payments %}
<tr class="{% cycle 'even-row' 'odd-row' %}">
<td>{{ payment.purpose }}</td>
<td>{{ payment.amount|euro }}</td>
<td>{% if payment.date %}{{ payment.date|date:"d.m." }}{% else %}-{% endif %}</td>
</tr>
{% endfor %}
</table>
<p>
Details zu den Spenden und Rückzahlungen an die Leute, die die Ausgaben geleistet haben,
lassen wir hier erstmal weg. Wer's ganz genau wissen will, kann ja fragen.
</p>
<p>
Nicht aufgelistet sind kurzfristige Dinge für die Vorbereitungsaktionen, also z.B. Suff und Sprit, den wir für
die Arbeitseinsätze gekauft und auch direkt vernichtet haben. Danke an dieser Stelle nochmal allen für die
jeweiligen Einkäufe und die unbezahlbare Arbeitskraft!
</p>
{% endblock %}
@@ -1,18 +0,0 @@
{% extends "gaehsnitz/base.html" %}
{% load static %}
{% block content %}
<h2>&#128736; Donnerstag 06.</h2>
<p>ganz viel Aufbau</p>
<h2>&#128736; Freitag 07.</h2>
<p>Warm-Up</p>
<h2>&#128736; Samstag 08.</h2>
<p>ganz viel Live-Mucke</p>
<h2>&#128736; Sonntag 09.</h2>
<p>ganz viel Abbau</p>
{% endblock %}
+3 -4
View File
@@ -1,11 +1,10 @@
from django.urls import path
from gaehsnitz.views import NewsView, AToZView, ProgramView, FinanceView, ForBandsView
from gaehsnitz.views import NewsView, ForBandsView, Archive2022View, Archive2024View
urlpatterns = [
path("", NewsView.as_view(), name="news"),
path("atoz", AToZView.as_view(), name="atoz"),
path("program", ProgramView.as_view(), name="program"),
path("finance", FinanceView.as_view(), name="finance"),
path("for-bands", ForBandsView.as_view(), name="for-bands"),
path("archive/2022", Archive2022View.as_view(), name="archive-2022"),
path("archive/2024", Archive2024View.as_view(), name="archive-2024"),
]
+51 -21
View File
@@ -14,27 +14,17 @@ class GaehsnitzTemplateView(TemplateView):
context = super().get_context_data(**kwargs)
delta_til_start = festival_start_date - date.today()
days_til_start = max(delta_til_start.days, 0)
context.update({
"days_til_festival_start": days_til_start,
})
context.update(
{
"days_til_festival_start": days_til_start,
}
)
return context
class NewsView(GaehsnitzTemplateView):
template_name = "gaehsnitz/news.html"
class AToZView(GaehsnitzTemplateView):
template_name = "gaehsnitz/atoz.html"
class ProgramView(GaehsnitzTemplateView):
template_name = "gaehsnitz/program.html"
class FinanceView(GaehsnitzTemplateView):
template_name = "gaehsnitz/finance.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@@ -55,14 +45,54 @@ class FinanceView(GaehsnitzTemplateView):
displayed_payments.append(Payment(purpose="Bands", amount=band_sum))
context.update({
"total_donations": total_donations,
"total_payments": total_payments,
"total_balance": total_balance,
"payments": displayed_payments,
})
context.update(
{
"total_donations": total_donations,
"total_payments": total_payments,
"total_balance": total_balance,
"payments": displayed_payments,
}
)
return context
class ForBandsView(GaehsnitzTemplateView):
template_name = "gaehsnitz/for-bands.html"
class Archive2022View(GaehsnitzTemplateView):
template_name = "gaehsnitz/archive-2022.html"
class Archive2024View(GaehsnitzTemplateView):
template_name = "gaehsnitz/archive-2024.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
donations = Donation.objects.filter(date__year=2024)
payments = Payment.objects.filter(date__year=2024)
total_donations = donations.aggregate(sum=Sum("amount"))["sum"] or 0
total_payments = payments.aggregate(sum=Sum("amount"))["sum"] or 0
total_balance = total_donations - total_payments
band_sum, displayed_payments = 0, []
for pay in payments.order_by("date"):
if pay.purpose.startswith("Band"):
band_sum += pay.amount
else:
displayed_payments.append(pay)
displayed_payments.append(Payment(purpose="Bands", amount=band_sum))
context.update(
{
"total_donations": total_donations,
"total_payments": total_payments,
"total_balance": total_balance,
"payments": displayed_payments,
}
)
return context
+1 -1
View File
@@ -2,6 +2,6 @@ import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gaehsnitzproject.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gaehsnitzproject.settings")
application = get_wsgi_application()
+3 -2
View File
@@ -1,11 +1,12 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gaehsnitzproject.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gaehsnitzproject.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
@@ -17,5 +18,5 @@ def main():
execute_from_command_line(sys.argv)
if __name__ == '__main__':
if __name__ == "__main__":
main()
+21
View File
@@ -0,0 +1,21 @@
[project]
name = "gaehsnitz"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = [
"django==6.0.3",
"gunicorn==26.0.0",
"psycopg[binary]==3.3.3",
]
[dependency-groups]
dev = [
"ruff==0.15.8",
]
[tool.ruff]
target-version = "py314"
line-length = 120
[tool.ruff.lint]
select = ["E", "F", "W", "I"]
+2 -5
View File
@@ -1,7 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":configMigration"
]
$schema: "https://docs.renovatebot.com/renovate-schema.json",
extends: ["config:recommended", ":configMigration"],
}
-3
View File
@@ -1,3 +0,0 @@
django==6.0.1
gunicorn==24.1.1
psycopg[binary]==3.3.2