API
جستجو هم یک نمایه ایستاست: حدود 7,000 فایل کوچک که روی هم همه نامهای هر سریال، فیلم و فرد را به همه زبانها پوشش میدهند. هر پرسوجو فقط به یکی از آنها نیاز دارد.
فایلها
https://api.watchittrackit.com/v1/search/manifest.jsonhttps://api.watchittrackit.com/v1/search/{build}/tree.jsonhttps://api.watchittrackit.com/v1/search/{build}/l/{hex}.jsonhttps://api.watchittrackit.com/v1/search/{build}/s/{hex}.jsonhttps://api.watchittrackit.com/v1/search/recent.json
جستجوی یک پرسوجو
v1/search/manifest.jsonرا بخوانید تا شناسه build فعلی را بگیرید.v1/search/{build}/tree.jsonرا بخوانید. این فایل در یک build هرگز تغییر نمیکند، پس یک بار دریافتش کنید.- پرسوجو را نرمال کنید: آن را به حروف کوچک تبدیل کنید و اعراب و نشانههای نگارشی را حذف کنید. آن را با بلندترین واژهاش که ایستواژه نیست جستجو کنید.
- با آن واژه درخت را پیمایش کنید تا فایلش را پیدا کنید: یک bucket در
l/یا، اگر واژه دقیقاً روی یک پیشوند تقسیم تمام شود، یک خلاصه درs/. نام فایلها هگزادسیمال بایتهای UTF-8 پیشوند است. - مواردی را نگه دارید که هر واژه پرسوجو آغاز یکی از واژههای نام باشد. نامهایی را که با کل پرسوجو شروع میشوند اول بگذارید، سپس بر اساس محبوبیت مرتب کنید.
v1/search/recent.jsonرا اعمال کنید: این فایل رکوردهایی را که از زمان build تغییر کردهاند فهرست میکند. موارد نمایه برای آن رکوردها را کنار بگذارید و بهجایشان از اینها استفاده کنید. این فایل با ویرایش رکوردها تغییر میکند، پس برای گرفتن نسخه تازه یک رشته پرسوجو اضافه کنید که هر چند دقیقه تغییر کند (?w=بهعلاوه بازه 5 دقیقهای فعلی).
موارد
هر مورد یک آرایه است:
| جایگاه | نوع | توضیح |
|---|---|---|
| 0 | string | نوع رکورد. |
| 1 | number | شناسه رکورد. |
| 2 | string | نامی که مطابقت داشت، به هر زبانی که باشد. |
| 3 | number | رتبه در نوع خود: 1,000,000 محبوبترین است. |
| 4 | string | slug رکورد. |
| 5 | number | null | سال، برای آثار. |
| 6 | string | null | مسیر تصویر بندانگشتی. |
نمونه (JavaScript)
const BASE = "https://api.watchittrackit.com/v1/search"
const STOPWORDS = new Set(["a", "an", "and", "the", "of", "in", "on", "to", "for", "at", "by", "with", "or",
"de", "del", "la", "le", "les", "el", "los", "las", "lo", "un", "une", "et", "du", "des", "da", "do", "dos",
"der", "die", "das", "und", "ein", "eine", "den", "dem", "von", "zu", "il", "i", "e", "di", "y", "en", "het", "een", "van"])
const normalize = (s) => s.normalize("NFKD").replace(/\p{M}/gu, "").toLowerCase()
.replace(/[^\p{L}\p{N}]+/gu, " ").trim()
const hex = (s) => [...new TextEncoder().encode(s)].map((b) => b.toString(16).padStart(2, "0")).join("")
async function search(query) {
const { build } = await fetch(`${BASE}/manifest.json`).then((r) => r.json())
const tree = await fetch(`${BASE}/${build}/tree.json`).then((r) => r.json())
const q = normalize(query)
const words = q.split(" ").filter(Boolean)
const real = words.filter((w) => !STOPWORDS.has(w))
const word = (real.length ? real : words).sort((a, b) => [...b].length - [...a].length)[0]
// Walk the tree: descend while the prefix is split; stop at a bucket or a summary.
let key = "", file
for (const c of word) {
if (tree[key + c]) { key += c; continue }
const starts = tree[key] ?? []
const start = starts.filter((s) => s <= c).pop() ?? starts[0] ?? c
file = `l/${hex(key + start)}.json`
break
}
file ??= `s/${hex(key)}.json`
const res = await fetch(`${BASE}/${build}/${file}`)
let entries = res.ok ? await res.json() : []
// Records changed since the build replace the index's entries for them.
// The query string changes every 5 minutes, so caches don't serve an old copy.
const recent = await fetch(`${BASE}/recent.json?w=${Math.floor(Date.now() / 300000)}`).then((r) => r.json())
entries = entries.filter(([type, id]) => !(`${type}:${id}` in recent.records))
entries.push(...Object.values(recent.records).flat())
const seen = new Set()
return entries
.filter((e) => { const n = normalize(e[2]).split(" "); return words.every((w) => n.some((x) => x.startsWith(w))) })
.sort((a, b) => Number(normalize(b[2]).startsWith(q)) - Number(normalize(a[2]).startsWith(q)) || b[3] - a[3])
.filter(([type, id]) => !seen.has(`${type}:${id}`) && seen.add(`${type}:${id}`))
.slice(0, 30)
}
// [["tv", 81189, "Breaking Bad", 999998, "breaking-bad", 2008, "/images/tv/81189/….t.jpg"], …]
console.log(await search("breaking bad"))نمایه هر روز از نو ساخته میشود. فایلهای یک build هرگز تغییر نمیکنند، پس هر قدر که بخواهید آنها را کش کنید؛ فقط manifest و recent.json تغییر میکنند.