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 23, 2020
1 parent 940a420 commit a08490c
Show file tree
Hide file tree
Showing 23 changed files with 986 additions and 16 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ repos:
rev: "4.3.21-2"
hooks:
- id: isort
args: [-sg **/*.txt]
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ Etimologi: [Arab] (n) (sg) (f/m) رُوْحٌ rūh: tiupan; sesuatu yang membua
Gabungan Kata
roh Kudus; roh suci
```
Fitur khusus pengguna untuk memanfaatkan fitur saran entri yang mirip apabila entri tidak dapat ditemukan.

```python
>>> auth = AutentikasiKBBI("[email protected]", "password_saya")
>>> huk = KBBI("huk", auth)
>>> print(roh)
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
```

Fitur khusus pengguna yang didukung saat ini adalah etimologi, entri terkait
(kata turunan, gabungan kata, peribahasa, dan idiom), dan batas pencarian yang
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 = None
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.saran_entri and fitur_pengguna:
kbbi["saran_entri"] = self.saran_entri
return kbbi

def __str__(self, contoh=True, terkait=True, fitur_pengguna=True):
if self.saran_entri and fitur_pengguna:
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 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 a08490c

Please sign in to comment.