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:
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.
Deretter fyller ein enkelt inn dialogen som føljer.
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.
Når kontrollpanelet dykkar opp, klikkar ein ganske enkelt på New, og fyll ut felta i dialogen som kjem opp.
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.
- Sjølv om Ordbanken virkar om ein legg inn Cygwin med make og util-linux [↩]






