Ordbanken i nettlesaren

July 8th, 2009

Forrige veka, skreiv eg om den framifrå ordlista Ordbanken, som gjev oss båe nynorsk og bokmål ordliste direkte i terminalen. Det er veldig kjekt, men kva med dei gongane ein ønskjer å nytta nettlesaren? I ein kommentar frå Simon kom det fram at det kunne vera ønskjeleg,  og sjølv om ein kan nytta Søk i Elektroniske Ordbøker, er eg ikkje interessert i eit kompromiss; eg vil ha Ordbanken.

Eg såg dessuten i loggane mine at ein stakkar hadde forvilla seg inn på det nemnte innlegget ved å søkja etter «Legg til søk i bokmålsordboka i Internet Explorer», så då kan eg jo dekka det òg, i Firefox vel å merka. Dei som nyttar IE bør uansett testa ut Firefox 3.5, med snaddar som <video> osb.

Ein av dei hendige funksjonane eg nemnte forrige gong, var at programmet kan skriva ut som html. Det gjer saka mykje enklare for oss, for då treng med berre henta inn søket frå brukaren, køyra programmet med dei rette parametrane, og skriva det attende til brukaren.

Det er to måtar me kan gjera dette på; me kan skriva eit tenarsideskript og køyra det på ein tenar som til døme denne her, eller me kan skriva ein liten og nett vevtenar berre for denne jobben. Ei kjekk ting med Ordbanken, er at heile ordlista ligg lokalt. Dermed kan me nytta ho i heimen, på toget eller kor som helst. Derfor gjeng eg for den siste løysinga, slik at me ikkje bryt me slik ein hendig funksjon. La oss sjå kor enkelt me kan gjera dette med nokre få linjer Python.

Ein av tinga eg likar med Python, er at det har eit stort bibliotek som standard. Det har kanskje ikkje eit like stort eksternt bibliotek som Perls CPAN endå, men det treng me ikkje bry oss om: Alt med treng for denne oppgåva, ligg allereie i biblioteket.

Komma igang

For at me skal kunne nytta Ordbanken via nettlesaren, må me først ha eit skjema å skriva orda inn i. Med mine fantastiske evnar har eg laga eit serdeles estetisk skjema:

nettordbanken

Med dette på plass, er med klar for å skriva tenaren. Det er ein enkelt jobb, av di BaseHTTPServer-modulen har alle brikkene med treng. Alt me må gjera, er å definera kva som skal skje når tenaren mottar ein spørjing, ved å laga ein subklasse av BaseHTTPRequestHandler. Av di med berre treng GET, treng me ikkje implementera støtte for POST.

Ettersom me berre har to moglegheitar, blir tenaren vår særs enkel. Om brukaren ikkje har skreve noko ord, gjev me han skjemaet. Hev han allereie skreve eit ord, gjer me han utskrifta frå Ordbanken. Då treng me ikkje tenka på 404 meldingar osb. Koden for dette blir dermed kort og grei (code2html stal alle innrykka mine:

def do_GET(self):

“”

Gjev spørjeskjemaet eller slå opp ord.

“”

self.send_response(200) #skjemaet fins alltid, inga 404

apply(self.send_header, self.ctype) #send header
self.end_headers()

# hent ut evt skjemadata
url = urlparse.urlparse(self.path)

data = urlparse.parse_qs(url.query)

# så opp ord, eller skriv skjemaet

if(“ord” in data):
self.wfile.write(self.oppslag(data))

else:
self.wfile.write(self.skjema) # self.skjema er html’en til skjemaet vist ovanfor

Nå som me har GET-handteraren på plass, må me skriva oppslag-metoden me kallar på ovanfor. Den er heller ikkje mykje hokus pokus. Me sjekkar om brukaren har valt språk, bygg opp kommandolinja til Ordbanken, og nyttar subprocess-modulen til å køyra programmet. Det som er kjekt med subprocess, er at programmet blir køyrd direkte, uten å gå innom skallet. Dermed treng me ikkje bekymra oss for at slemmingar skriv injections. Når me har køyrd programmet, sjekkar me om det gjekk bra. Gjekk det bra, svarar metoden med den vanlege utskrifta frå Ordbanken. Gjekk det dårleg, skriv den ut feilutskrifta.

def oppslag(self, data):

“”
Slår opp ord ved å nytta ordbanken.
“”

args = ["ordbanken", "--html"] #her legg ein til -r for regex

#sett språk
if data.has_key(“språk”) and data["språk"] == “nb”:

args.append(“-s nb”)

#legg til ord og evt filtre
args += [elem for elem in data["ord"][0].split()]

#køyr kommandoen
ordbanken = Popen((args), stdout=PIPE, stderr=PIPE)

retval = ordbanken.wait()

#les frå stdout om ting gjekk bra
if retval == 0:

return ordbanken.stdout.read()
else:
return ordbanken.stdout.read()

Då er subklassen vår ferdig, og alt me manglar er å be HTTPServer nytta han. I tillegg nyttar me optparse, så me slipp å hardkoda adresse og port for tenaren vår:


if __name__ == “__main__”:

from optparse import OptionParser

parser = OptionParser()

parser.add_option(“-p”, “–port”, dest=“port”, default=8080, \
help=“Porten tenaren nyttar”)

parser.add_option(“-a”, “–addr”, dest=“addr”, default=“localhost”, \
help=“Adressa tenaren nyttar”)

opts, args = parser.parse_args()

try:

httpd = HTTPServer((opts.addr, int(opts.port)), NettOrdBanken)

print(“Vevtenaren starta pÃ¥ %s port %s.” % (opts.addr, opts.port))

httpd.serve_forever()

except KeyboardInterrupt:
print(“Eg døyr!”)

httpd.socket.close()

Det ferdige skriptet finn dykk her.

I bruk

Å nytta vevtenaren er særs enkelt. Berre køyr skriptet gjennom python eller gjer det køyrbart

egil@morgenstern [nettordbanken] $ python nettordbanken.py
Vevtenaren starta på localhost port 8080

Så er det berre å peika nettlesaren på adressa, som standard er http://localhost:8080. Skriv me no til døme «virke verb», får me følgjande utskrift attende frå tenaren:

virke virk verb imp
virke virka verb imp
virke virke verb imp
virke virka verb inf
virke virke verb inf
virke virkast verb inf pres st-form
virke virka verb perf-part
virke virkt verb perf-part
virke virkar verb pres
virke virker verb pres
virke virka verb pret
virke virkte verb pret

Vips, så har me Ordbanken ikkje berre i terminalen, men i nettlesaren òg. :)

Integrert i adresselinja

Skjemaet er ikkje mykje pent å sjå på, men det er heller ikkje tiltenkt masse bruk. Skal ein først ha Ordbanken i nettlesaren, må den vera like enkel å nytta som den vanlege utgåva. Eg har inga planar om å visa korleis ein gjer det med Internet Explorer1, men held meg til Firefox og Opera. Eg nyttar sjølv Firefox, men siden det er ein (av mange) funksjonar som har sitt opphav i Opera, tek eg med den òg. (Eg gidd ikkje legg inn masse pakkar berre for å ta med Konqueror òg) Du må berre skriva ein innspel om du nyttar noko anna.

Når det er sagt, nyttar eg den vanlege adresselinja, ikkje det nyare søkjefeltet ein finn til høgre. Litt av poenget forsvinn om ein ikkje kan nytta dei gode gamle hurtigtastane :) Det er ikke særleg vanskeleg, og er veldig likt i båe Firefox og Opera. Høgreklikk på tekstfeltet, og vel det valet som inneheld «Search»: «Add a Keyword for this Search…» for Firefox, og «Create Search» for Opera.

Første steg i Firefox

Første steg i Firefox

Første steg i Opera

Første steg i Opera

Deretter fyller ein enkelt inn dialogen som føljer.

Andre steg i Firefox

Andre steg i Firefox

Andre steg i Opera

Andre steg i Opera

Dermed kan ein enkelt søkja i Ordbanken berre ved å skriva «ord <ditt ord>» i adressefeltet, så kjem svaret frå Ordbanken rett i nettlesaren. Då er det berre ein ting att å gjera før me kan sjå oss fornøgd, automatisk oppstart.

Automatisk oppstart

For at me skal kunne nytta Ordbanken i nettlesaren, er med avhengig av at tenarprosessen køyrer i bakgrunnen. Første gong ein testar det, kan ein køyre det i eit terminalvindauge. Det er derimot inga permanent løysing. Skal me nytta det spontant når me lurar på eit ord, må me fram me litt automatikk. Eg har inga planer om å visa korleis ein gjer det på alle posix-kompatible system som python måtte køyre på, men held meg til Gnome. (Eg kan òg nemna Fluxbox, legg skriptet litt ein plass i ~/.fluxbox/startup)

For å starta eit program kvar gong ein loggar inn, veljar ein «Startup Applications» under System->Preferences.

Menyval

Menyval

Når kontrollpanelet dykkar opp, klikkar ein ganske enkelt på New, og fyll ut felta i dialogen som kjem opp.

Lag ny automatisk oppgåve

Lag ny automatisk oppgåve

Fyll ut egna namn og kommentar, og bla deg fram til der du lagra skriptet. Av di eg ikkje har gidda å gjera det køyrbart, skriv eg python foran etterpå :) . Neste gang du loggar inn, vil tenaren køyre i bakgrunnen, og Ordbanken er klar til bruk.

Vote:
  1. Sjølv om Ordbanken virkar om ein legg inn Cygwin med make og util-linux []

Leave a Reply