Skip to content

Commit

Permalink
Tambahkan fitur saran entri lain yang mirip
Browse files Browse the repository at this point in the history
  • Loading branch information
maulana saputra authored and laymonage committed May 24, 2020
1 parent 940a420 commit b5e17eb
Show file tree
Hide file tree
Showing 22 changed files with 999 additions and 18 deletions.
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ roh Kudus; roh suci
```

Fitur khusus pengguna yang didukung saat ini adalah etimologi, entri terkait
(kata turunan, gabungan kata, peribahasa, dan idiom), dan batas pencarian yang
lebih besar.
(kata turunan, gabungan kata, peribahasa, dan idiom), saran entri terkait
ketika entri tidak ditemukan, dan batas pencarian yang lebih besar.

Untuk mendapatkan representasi `str`-nya tanpa fitur entri terkait, gunakan
`__str__(terkait=False)`.
Expand All @@ -181,6 +181,26 @@ Etimologi: [Arab] (n) (sg) (f/m) رُوْحٌ rūh: tiupan; sesuatu yang membua
3. (n) (ki) semangat; spirit
```

Untuk memanfaatkan fitur saran entri yang mirip apabila entri tidak dapat
ditemukan, gunakan objek `KBBI` yang terdapat pada objek `TidakDitemukan`
melalui atribut `objek`.

```python
>>> from kbbi import TidakDitemukan
>>> try:
... huk = KBBI("huk", auth)
... except TidakDitemukan as e:
... huk = e.objek
...
>>> print(huk)
Berikut beberapa saran entri lain yang mirip.
auk, buk (1), buk (2), cuk, duk, hak (1), hak (2), hak (3), hak (4), huh, hun, hus, Hut, kuk (1), kuk (2), luk, muk, suk, tuk (1), yuk (1), yuk (2), DUK, HUT, KUK, UK, hub (2), Hud, tuk (2), guk
>>> print(huk.serialisasi())
{'pranala': 'https://kbbi.kemdikbud.go.id/entri/huk', 'entri': [], 'saran_entri': ['auk', 'buk (1)', 'buk (2)', 'cuk', 'duk', 'hak (1)', 'hak (2)', 'hak (3)', 'hak (4)', 'huh', 'hun', 'hus', 'Hut', 'kuk (1)', 'kuk (2)', 'luk', 'muk', 'suk', 'tuk (1)', 'yuk (1)', 'yuk (2)', 'DUK', 'HUT', 'KUK', 'UK', 'hub (2)', 'Hud', 'tuk (2)', 'guk']}
>>> print(huk.saran_entri)
['auk', 'buk (1)', 'buk (2)', 'cuk', 'duk', 'hak (1)', 'hak (2)', 'hak (3)', 'hak (4)', 'huh', 'hun', 'hus', 'Hut', 'kuk (1)', 'kuk (2)', 'luk', 'muk', 'suk', 'tuk (1)', 'yuk (1)', 'yuk (2)', 'DUK', 'HUT', 'KUK', 'UK', 'hub (2)', 'Hud', 'tuk (2)', 'guk']
```

Untuk menonaktifkan fitur khusus pengguna (selain batas pencarian yang lebih
besar), tambahkan argumen `fitur_pengguna=False` pada pemanggilan `__str__`
atau `serialisasi`.
Expand Down
34 changes: 30 additions & 4 deletions src/kbbi/kbbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def __init__(self, kueri, auth=None):
:type auth: AutentikasiKBBI
"""
self.nama = kueri
self.entri = []
self.saran_entri = []
self._init_lokasi()
self._init_sesi(auth)
laman = self.sesi.get(f"{self.host}/{self.lokasi}")
Expand Down Expand Up @@ -74,12 +76,20 @@ def _cek_galat(self, laman):
if "Beranda/BatasSehari" in laman.url:
raise BatasSehari()
if "Entri tidak ditemukan." in laman.text:
raise TidakDitemukan(self.nama)
self._init_saran(laman)
raise TidakDitemukan(self.nama, objek=self)

def _init_saran(self, laman):
if "Berikut beberapa saran entri lain yang mirip." not in laman.text:
return
sup = BeautifulSoup(laman.text, "html.parser")
self.saran_entri = [
saran.text.strip() for saran in sup.find_all(class_="col-md-3")
]

def _init_entri(self, laman):
sup = BeautifulSoup(laman.text, "html.parser")
estr = ""
self.entri = []
label = sup.find("hr").next_sibling
while not (label.name == "hr" and label.get("style") is None):
if label.name == "h2":
Expand All @@ -99,14 +109,22 @@ def serialisasi(self, fitur_pengguna=True):
:returns: Dictionary hasil serialisasi
:rtype: dict
"""
return {
kbbi = {
"pranala": f"{self.host}/{self.lokasi}",
"entri": [
entri.serialisasi(fitur_pengguna) for entri in self.entri
],
}
if self.terautentikasi and fitur_pengguna and not self.entri:
kbbi["saran_entri"] = self.saran_entri
return kbbi

def __str__(self, contoh=True, terkait=True, fitur_pengguna=True):
if self.terautentikasi and fitur_pengguna and self.saran_entri:
return (
"Berikut beberapa saran entri lain yang mirip.\n"
f"{', '.join(self.saran_entri)}"
)
return "\n\n".join(
entri.__str__(contoh, terkait, fitur_pengguna)
for entri in self.entri
Expand Down Expand Up @@ -558,8 +576,9 @@ class Galat(Exception):
class TidakDitemukan(Galat):
"""Galat ketika laman tidak ditemukan dalam KBBI."""

def __init__(self, kueri):
def __init__(self, kueri, objek=None):
super().__init__(f"{kueri} tidak ditemukan dalam KBBI.")
self.objek = objek


class TerjadiKesalahan(Galat):
Expand Down Expand Up @@ -787,6 +806,13 @@ def main(argv=None):
return 1
try:
laman = KBBI(args.laman, auth)
except TidakDitemukan as e:
laman = e.objek
if not args.json:
print(e)
if (laman.saran_entri and args.pengguna) or args.json:
print(_keluaran(laman, args))
return 1
except Galat as e:
print(e)
return 1
Expand Down
23 changes: 18 additions & 5 deletions tests/_mock.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
from kbbi import KBBI, AutentikasiKBBI, GagalAutentikasi
from kbbi import KBBI, AutentikasiKBBI, GagalAutentikasi, TidakDitemukan


class MockKBBI(KBBI):
host = "http://localhost:8000"
_host = KBBI.host
lokasi = None

def __init__(self, kueri, auth=None, lokasi=None):
self._auth = auth
self.lokasi = self.lokasi or lokasi
self._lokasi = lokasi
self.lokasi = lokasi
super().__init__(kueri, auth)

def _cek_autentikasi(self, laman):
super()._cek_autentikasi(laman)
self._kembalikan_host_lokasi()

def _kembalikan_host_lokasi(self):
self.host = self._host
if lokasi is None:
self.lokasi = self._lokasi
self.lokasi = self._lokasi

@classmethod
def _init_aman(cls, kueri, auth=None, lokasi=None):
try:
return cls(kueri, auth, lokasi)
except TidakDitemukan as e:
e.objek._kembalikan_host_lokasi()
return e.objek

def _init_lokasi(self):
if self.lokasi is not None:
Expand Down
11 changes: 6 additions & 5 deletions tests/buat_kasus.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"sage", # terdapat info (bahasa latin)
"semakin", # terdapat entri tanpa makna dan entri lain berupa rujukan
"tampak", # terdapat rujukan dengan nomor
"huk", # saran entri lain yang mirip apabila entri tidak dapat ditemukan
"idn45", # tidak ditemukan dan tidak ada saran entri lain yang mirip
]


Expand Down Expand Up @@ -124,15 +126,14 @@ def buat_semua_objek(daftar):
auth = MockAutentikasiKBBI("foo", "bar")
semua = {"auth": [], "nonauth": []}
for laman in daftar:
semua["auth"].append(MockKBBI(laman, auth))
semua["nonauth"].append(MockKBBI(laman))
semua["auth"].append(MockKBBI._init_aman(laman, auth))
semua["nonauth"].append(MockKBBI._init_aman(laman))
return semua


def buat_semua_kasus(semua, jenis):
for laman, objek in semua.items():
for buat in jenis:
buat(semua)
for buat in jenis:
buat(semua)


def main(daftar=None):
Expand Down
6 changes: 4 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,16 @@ def ambil_atau_simpan(dct, key, func):
@pytest.fixture
def aktual_objek(request, laman):
kueri = request.param
return ambil_atau_simpan(laman, kueri, lambda a: MockKBBI(a))
return ambil_atau_simpan(laman, kueri, lambda a: MockKBBI._init_aman(a))


@pytest.fixture
def aktual_objek_terautentikasi(request, autentikasi, laman_terautentikasi):
kueri = request.param
return ambil_atau_simpan(
laman_terautentikasi, kueri, lambda a: MockKBBI(a, autentikasi)
laman_terautentikasi,
kueri,
lambda a: MockKBBI._init_aman(a, autentikasi),
)


Expand Down
Loading

0 comments on commit b5e17eb

Please sign in to comment.