Skip to content

Commit

Permalink
Merge pull request #348 from boudicca-events/abl/sport-category
Browse files Browse the repository at this point in the history
Abl/sport category
  • Loading branch information
twatzl authored Mar 18, 2024
2 parents 90a63d5 + f9fe0a3 commit 79b8084
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 15 deletions.
1 change: 1 addition & 0 deletions SEMANTIC_CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ We use certain data types for the properties we expect.
* `MUSIC`: concerts or other events where the main focus is music
* `TECH`: event with technology as the focus
* `ART`: art exhibitions, comedy, theater, ...
* `SPORT`: everything to do with sports, either watching them or actively participate

### Location Properties

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ data class SearchDTO(
@RequestParam("durationLonger", required = false) var durationLonger: Double?,
@RequestParam("bandName", required = false) var bandName: String?,
@RequestParam("includeRecurring", required = false) var includeRecurring: Boolean?,
@RequestParam("sportParticipation", required = false) var sportParticipation: String?,
) {
constructor() : this(null, null, null, null, null, null, null, null, null, null, null, null)
constructor() : this(null, null, null, null, null, null, null, null, null, null, null, null, null)
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class EventService @Autowired constructor(
if (additionalFilter.isNotBlank()) {
queryParts.add(additionalFilter)
}
if (!searchDTO.sportParticipation.isNullOrBlank()) {
queryParts.add(equals("sport.participation", searchDTO.sportParticipation!!))
}
return and(queryParts)
}

Expand Down Expand Up @@ -188,6 +191,7 @@ class EventService @Autowired constructor(
EventCategory.MUSIC -> "music"
EventCategory.ART -> "miscArt"
EventCategory.TECH -> "tech"
EventCategory.SPORT -> "sport"
EventCategory.ALL -> "???"
EventCategory.OTHER -> null
}
Expand All @@ -209,6 +213,7 @@ class EventService @Autowired constructor(
EventCategory.MUSIC -> "Musik"
EventCategory.ART -> "Kunst"
EventCategory.TECH -> "Technologie"
EventCategory.SPORT -> "Sport"
EventCategory.ALL -> "Alle"
EventCategory.OTHER -> "Andere"
else -> "???"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ document.addEventListener("DOMContentLoaded", () => {
const resetSearchFormButton = document.getElementById("resetSearchForm");
const loadMoreButton = document.getElementById("loadMoreButton");
const categorySelect = document.getElementById("category");
const bandNameSelect = document.getElementById("bandName");
const musicFieldSet = document.getElementById("musicFieldSet");
const categoryFieldSets = document.querySelectorAll("[data-category-wanted]");

loadMoreButton.addEventListener("click", () => {
onLoadMoreSearch();
Expand Down Expand Up @@ -131,11 +130,18 @@ document.addEventListener("DOMContentLoaded", () => {

const onCategoryChange = () => {
let category = categorySelect.value;
if (category === "MUSIC") {
musicFieldSet.classList.remove("hidden");
} else {
bandNameSelect.selectedIndex = 0;
musicFieldSet.classList.add("hidden");
for (fieldSet of categoryFieldSets) {
if (fieldSet.dataset["categoryWanted"] === category) {
fieldSet.classList.remove("hidden");
} else {
for (select of fieldSet.querySelectorAll("select")) {
select.selectedIndex = 0;
}
for (input of fieldSet.querySelectorAll("input")) {
input.value = "";
}
fieldSet.classList.add("hidden");
}
}
};
categorySelect.addEventListener("change", onCategoryChange);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
</div>
</fieldset>

<fieldset id="musicFieldSet">
<fieldset data-category-wanted="MUSIC">
<legend><strong>Musik</strong></legend>
<div class="header-search-filter">
<div class="header-date-search">
Expand All @@ -168,6 +168,22 @@
</div>
</fieldset>

<fieldset data-category-wanted="SPORT">
<legend><strong>Sport</strong></legend>
<div class="header-search-filter">
<div class="header-date-search">
<div class="filter-input-wrapper">
<label for="sportParticipation" class="filter-label">Teilnahme</label>
<select name="sportParticipation" id="sportParticipation">
<option value="">Beliebig</option>
<option value="active">Zum Mitmachen</option>
<option value="watch">Zum Zuschauen</option>
</select>
</div>
</div>
</div>
</fieldset>

<fieldset>
<legend><strong>Accessibility</strong></legend>
<div class="header-search-filter">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ enum class EventCategory(val types: Set<String>) {
"museen",
"museum",
"ausstellung",
"musical"
"musical",
"brauchtum",
)
),
TECH(setOf("techmeetup", "technology", "technologie"));
TECH(setOf("techmeetup", "technology", "technologie")),
SPORT(setOf("sport", "football", "soccer"));

companion object {
fun getForType(type: String?): EventCategory? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class AlpenvereinCollector : TwoStepEventCollector<String>("alpenverein") {
data[SemanticKeys.URL] = event
data[SemanticKeys.SOURCES] = event
data[SemanticKeys.TYPE] = "sport"
data["sport.participation"] = "active"
data[SemanticKeys.DESCRIPTION] = eventSite.select("div.elementBoxSheet div.elementText").text()

if (endDate != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,29 +81,44 @@ class LinzTermineCollector : EventCollector {
} else {
""
}
val additionalProperties = mapAdditionalProperties(event)

for (date in event.dates) {
mappedEvents.add(
Event(
event.name,
date.first,
mapOf(
SemanticKeys.ENDDATE to date.second.format(DateTimeFormatter.ISO_DATE_TIME),
SemanticKeys.TYPE to (event.type ?: ""),
SemanticKeys.TYPE to mapEventType(event.type),
SemanticKeys.DESCRIPTION to description,
SemanticKeys.PICTUREURL to pictureUrl,
SemanticKeys.REGISTRATION to (if (event.freeOfCharge) "FREE" else "TICKET"),
SemanticKeys.URL to event.url,
SemanticKeys.LOCATION_NAME to (location?.name
?: event.locationFallbackName), //they do not include all locations in their location.xml files -.-
SemanticKeys.SOURCES to event.url + "\n" + eventsBaseUrl + "\n" + locationBaseUrl
).filter { it.value.isNotBlank() }
).plus(additionalProperties).filter { it.value.isNotBlank() }
)
)
}
}
return mappedEvents
}

private fun mapAdditionalProperties(event: LinzTermineEvent): Map<String, String> {
val additionalProperties = mutableMapOf<String, String>()

if (event.type?.first == 401) {
additionalProperties["sport.participation"] = "watch"
}
if (event.type?.first == 402) {
additionalProperties["sport.participation"] = "active"
}

return additionalProperties
}

private fun parseEvents(): List<LinzTermineEvent> {
val formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd kk:mm:ss")

Expand Down Expand Up @@ -133,7 +148,7 @@ class LinzTermineCollector : EventCollector {
LinzTermineEvent(
it.attr("id").toInt(),
it.select("title").text(),
it.select("tags").first()?.child(0)?.text(),
findTag(it),
it.select("date").map {
Pair(
LocalDateTime.parse(it.attr("dFrom"), formatter).atZone(ZoneId.of("Europe/Vienna"))
Expand All @@ -151,6 +166,15 @@ class LinzTermineCollector : EventCollector {
}.distinctBy { it.id }
}

private fun findTag(event: Element): Pair<Int, String>? {
val tagElement = event.select("tags").first()?.child(0)
return if (tagElement != null) {
Pair(tagElement.attr("id").toInt(), tagElement.text())
} else {
null
}
}

private fun findLocationId(event: Element): Int? {
val idAttr = event.select("location").attr("id")
return if (!idAttr.isNullOrBlank()) {
Expand Down Expand Up @@ -184,6 +208,16 @@ class LinzTermineCollector : EventCollector {
}.associateBy { it.id }
}

private fun mapEventType(eventType: Pair<Int, String>?): String {
if (eventType == null) {
return ""
}
if (eventType.first == 401 || eventType.first == 402) {
return "sport"
}
return eventType.second
}

private fun loadXml(s: String): Document {
return Jsoup.parse(fetcher.fetchUrl(s), Parser.xmlParser())
}
Expand All @@ -197,7 +231,7 @@ class LinzTermineCollector : EventCollector {
data class LinzTermineEvent(
val id: Int,
val name: String,
val type: String?,
val type: Pair<Int, String>?,
val dates: List<Pair<OffsetDateTime, OffsetDateTime>>,
val freeOfCharge: Boolean,
val url: String,
Expand Down

0 comments on commit 79b8084

Please sign in to comment.