update
This commit is contained in:
@@ -7,6 +7,7 @@ landen nicht in der Datenbank.
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import random
|
import random
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
@@ -172,14 +173,43 @@ async def discover(filter_, limit=40):
|
|||||||
return treffer
|
return treffer
|
||||||
|
|
||||||
|
|
||||||
|
def ohne_zeichen(text):
|
||||||
|
"""Umlaute und Akzente auf den Grundbuchstaben zurückführen."""
|
||||||
|
zerlegt = unicodedata.normalize("NFD", text)
|
||||||
|
return "".join(z for z in zerlegt if not unicodedata.combining(z))
|
||||||
|
|
||||||
|
|
||||||
async def search(query, limit=24):
|
async def search(query, limit=24):
|
||||||
|
# TMDB findet angefangene Wörter nur ohne Umlaut: "Wilden Hüh" liefert
|
||||||
|
# nichts, "Wilden Huh" die drei Hühner-Filme. Wer beim Tippen sucht,
|
||||||
|
# steht sonst vor einer leeren Seite. Also beide Schreibweisen fragen.
|
||||||
|
schlicht = ohne_zeichen(query)
|
||||||
|
begriffe = [query] if schlicht == query else [query, schlicht]
|
||||||
|
|
||||||
|
async def einmal(begriff):
|
||||||
|
try:
|
||||||
|
resp = await http.get(
|
||||||
|
"/search/movie",
|
||||||
|
params={
|
||||||
|
"query": begriff,
|
||||||
|
"language": LANGUAGE,
|
||||||
|
"include_adult": "false",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json().get("results", [])
|
||||||
|
except httpx.HTTPError:
|
||||||
|
return []
|
||||||
|
|
||||||
async with client() as http:
|
async with client() as http:
|
||||||
resp = await http.get(
|
results = []
|
||||||
"/search/movie",
|
gesehen = set()
|
||||||
params={"query": query, "language": LANGUAGE, "include_adult": "false"},
|
# Die Treffer der wörtlichen Suche stehen vorn
|
||||||
)
|
for liste in await asyncio.gather(*(einmal(b) for b in begriffe)):
|
||||||
resp.raise_for_status()
|
for eintrag in liste:
|
||||||
results = resp.json().get("results", [])
|
if eintrag["id"] not in gesehen:
|
||||||
|
gesehen.add(eintrag["id"])
|
||||||
|
results.append(eintrag)
|
||||||
|
|
||||||
# Ohne Poster taugt eine Kachel nichts, und Namenlose sind fast immer
|
# Ohne Poster taugt eine Kachel nichts, und Namenlose sind fast immer
|
||||||
# Dubletten oder Making-ofs
|
# Dubletten oder Making-ofs
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import MovieCard from './MovieCard.vue'
|
import MovieCard from './MovieCard.vue'
|
||||||
import { filterParameter } from '../filter.js'
|
import { filterParameter } from '../filter.js'
|
||||||
|
|
||||||
// Der Ausgangsfilm steht als erste Karte davor, macht einundzwanzig
|
// Der Ausgangsfilm steht als erste Karte davor, macht einundzwanzig
|
||||||
const TREFFER = 20
|
const TREFFER = 20
|
||||||
|
|
||||||
|
// Eine Detailkarte nimmt die halbe Breite ein, eine kompakte ein Achtel.
|
||||||
|
// Gleich viele Vorschläge wären mal eine Reihe, mal zehn.
|
||||||
|
const VORSCHLAEGE = { kompakt: 20, details: 8 }
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
filter: { type: Object, default: () => ({}) },
|
filter: { type: Object, default: () => ({}) },
|
||||||
ansicht: { type: String, default: 'kompakt' },
|
ansicht: { type: String, default: 'kompakt' },
|
||||||
@@ -16,7 +20,11 @@ const props = defineProps({
|
|||||||
const emit = defineEmits(['open', 'gestartet'])
|
const emit = defineEmits(['open', 'gestartet'])
|
||||||
|
|
||||||
const query = ref('')
|
const query = ref('')
|
||||||
const vorschlaege = ref([])
|
const gefunden = ref([])
|
||||||
|
// Beim Wechsel der Ansicht wird nur neu geschnitten, nicht neu gesucht
|
||||||
|
const vorschlaege = computed(() =>
|
||||||
|
gefunden.value.slice(0, VORSCHLAEGE[props.ansicht] ?? 8)
|
||||||
|
)
|
||||||
const gewaehlt = ref(null)
|
const gewaehlt = ref(null)
|
||||||
const treffer = ref([])
|
const treffer = ref([])
|
||||||
const laden = ref(false)
|
const laden = ref(false)
|
||||||
@@ -32,7 +40,7 @@ let laufendeTreffer = 0
|
|||||||
// dazu passt.
|
// dazu passt.
|
||||||
async function suchen(term) {
|
async function suchen(term) {
|
||||||
if (term.trim().length < 2) {
|
if (term.trim().length < 2) {
|
||||||
vorschlaege.value = []
|
gefunden.value = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const meine = ++laufende
|
const meine = ++laufende
|
||||||
@@ -41,7 +49,7 @@ async function suchen(term) {
|
|||||||
if (!resp.ok) throw new Error('Suche fehlgeschlagen')
|
if (!resp.ok) throw new Error('Suche fehlgeschlagen')
|
||||||
const daten = await resp.json()
|
const daten = await resp.json()
|
||||||
if (meine !== laufende) return
|
if (meine !== laufende) return
|
||||||
vorschlaege.value = daten.slice(0, 8)
|
gefunden.value = daten
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (meine === laufende) fehler.value = err.message
|
if (meine === laufende) fehler.value = err.message
|
||||||
}
|
}
|
||||||
@@ -50,7 +58,7 @@ async function suchen(term) {
|
|||||||
async function waehlen(film) {
|
async function waehlen(film) {
|
||||||
const meine = ++laufendeWahl
|
const meine = ++laufendeWahl
|
||||||
gewaehlt.value = film
|
gewaehlt.value = film
|
||||||
vorschlaege.value = []
|
gefunden.value = []
|
||||||
query.value = ''
|
query.value = ''
|
||||||
nachladen()
|
nachladen()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user