inaktive veranstaltungen zeigen keinen teilnahmeberreich mehr, veranstaltungsortsuche verbessert
This commit is contained in:
+26
-3
@@ -2,6 +2,7 @@ import os
|
||||
import uuid
|
||||
import secrets
|
||||
import hashlib
|
||||
import re
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@@ -1147,6 +1148,7 @@ def concert_detail(request: Request, concert_id: int):
|
||||
]
|
||||
attending_users = [item for item in attendance if item["status"] == "attending"]
|
||||
ticket_seekers = [item for item in attendance if item["status"] == "ticket_search"]
|
||||
maybe_users = [item for item in attendance if item["status"] == "maybe"]
|
||||
current_attendance = next(
|
||||
(item["status"] for item in attendance if item["user_id"] == user["id"]),
|
||||
None,
|
||||
@@ -1165,6 +1167,8 @@ def concert_detail(request: Request, concert_id: int):
|
||||
attending_count=len(attending_users),
|
||||
ticket_seekers=ticket_seekers,
|
||||
ticket_seeker_count=len(ticket_seekers),
|
||||
maybe_users=maybe_users,
|
||||
maybe_count=len(maybe_users),
|
||||
)
|
||||
|
||||
|
||||
@@ -1606,6 +1610,12 @@ def search_venues(q: str):
|
||||
return []
|
||||
|
||||
results = []
|
||||
query_tokens = [
|
||||
token
|
||||
for token in re.findall(r"[a-z0-9]+", q.lower())
|
||||
if len(token) >= 3
|
||||
]
|
||||
token_match = " AND ".join("name ILIKE %s" for _ in query_tokens) or "FALSE"
|
||||
|
||||
|
||||
# ========================================================
|
||||
@@ -1616,7 +1626,7 @@ def search_venues(q: str):
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
|
||||
cursor.execute("""
|
||||
cursor.execute(f"""
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
@@ -1633,6 +1643,7 @@ def search_venues(q: str):
|
||||
name ILIKE %s
|
||||
OR city ILIKE %s
|
||||
OR street ILIKE %s
|
||||
OR ({token_match})
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN LOWER(name) = LOWER(%s)
|
||||
@@ -1653,11 +1664,13 @@ def search_venues(q: str):
|
||||
|
||||
f"%{q}%",
|
||||
|
||||
*[f"%{token}%" for token in query_tokens],
|
||||
|
||||
q,
|
||||
|
||||
f"{q}%",
|
||||
|
||||
f"%{q}%"
|
||||
f"%{q}%",
|
||||
|
||||
))
|
||||
|
||||
@@ -1717,9 +1730,11 @@ def search_venues(q: str):
|
||||
"User-Agent": "PinguConcerts/1.0"
|
||||
}
|
||||
|
||||
external_query = re.sub(r"\bhall\b", "halle", q, flags=re.IGNORECASE)
|
||||
|
||||
params = {
|
||||
|
||||
"q": q,
|
||||
"q": external_query,
|
||||
|
||||
"format": "jsonv2",
|
||||
|
||||
@@ -1876,6 +1891,14 @@ def search_venues(q: str):
|
||||
|
||||
score = 0
|
||||
|
||||
name_tokens = re.findall(r"[a-z0-9]+", name_lower)
|
||||
matched_tokens = sum(
|
||||
any(candidate.startswith(token) or token.startswith(candidate)
|
||||
for candidate in name_tokens)
|
||||
for token in query_tokens
|
||||
)
|
||||
score += matched_tokens * 30
|
||||
|
||||
|
||||
if name_lower == query_lower:
|
||||
|
||||
|
||||
@@ -196,6 +196,8 @@
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if not concert.is_past %}
|
||||
|
||||
<section class="attendance-section" id="attendance">
|
||||
|
||||
<h2>
|
||||
@@ -241,6 +243,7 @@
|
||||
<details class="attendance-list">
|
||||
<summary>
|
||||
{{ attending_count }} Zusage{% if attending_count != 1 %}n{% endif %}
|
||||
· {{ maybe_count }} Vielleicht
|
||||
· {{ ticket_seeker_count }} sucht Ticket
|
||||
</summary>
|
||||
|
||||
@@ -260,6 +263,20 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>? Vielleicht</h3>
|
||||
|
||||
{% if maybe_users %}
|
||||
<ul>
|
||||
{% for maybe_user in maybe_users %}
|
||||
<li>{{ maybe_user.name }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>Noch keine Vielleicht-Angaben.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>🎟️ Sucht ein Ticket</h3>
|
||||
|
||||
@@ -279,6 +296,8 @@
|
||||
|
||||
</section>
|
||||
|
||||
{% endif %}
|
||||
|
||||
<section class="comments-section" id="comments">
|
||||
|
||||
<h2>💬 Kommentare</h2>
|
||||
|
||||
@@ -389,6 +389,27 @@ const selectedVenue =
|
||||
|
||||
|
||||
let searchTimeout = null;
|
||||
let venueRequestController = null;
|
||||
|
||||
|
||||
function clearVenueSelection() {
|
||||
|
||||
[
|
||||
"venue-id",
|
||||
"venue-name",
|
||||
"venue-city",
|
||||
"venue-street",
|
||||
"venue-postal-code",
|
||||
"venue-country",
|
||||
"venue-latitude",
|
||||
"venue-longitude"
|
||||
].forEach(
|
||||
id => {
|
||||
document.getElementById(id).value = "";
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
venueSearch.addEventListener(
|
||||
@@ -410,6 +431,8 @@ venueSearch.addEventListener(
|
||||
selectedVenue.style.display =
|
||||
"none";
|
||||
|
||||
clearVenueSelection();
|
||||
|
||||
|
||||
if (query.length < 2) {
|
||||
|
||||
@@ -426,7 +449,7 @@ venueSearch.addEventListener(
|
||||
);
|
||||
|
||||
},
|
||||
300
|
||||
450
|
||||
);
|
||||
|
||||
}
|
||||
@@ -443,9 +466,18 @@ async function searchVenues(
|
||||
|
||||
try {
|
||||
|
||||
if (venueRequestController) {
|
||||
venueRequestController.abort();
|
||||
}
|
||||
|
||||
venueRequestController = new AbortController();
|
||||
|
||||
const response =
|
||||
await fetch(
|
||||
`/api/venues/search?q=${encodeURIComponent(query)}`
|
||||
`/api/venues/search?q=${encodeURIComponent(query)}`,
|
||||
{
|
||||
signal: venueRequestController.signal
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -554,6 +586,10 @@ async function searchVenues(
|
||||
|
||||
} catch (error) {
|
||||
|
||||
if (error.name === "AbortError") {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(
|
||||
"Venue search failed:",
|
||||
error
|
||||
|
||||
Reference in New Issue
Block a user