Python ja CGI-ohjelmointi - Viikkotehtävä 2
Tehtävässä on tarkoitus oppia perusteet CGI-ohjelmoinnista ja samalla ymmärtää HTTP-protokollan tilaton toimintatapa. Jokainen pyyntö www-palvelimelle on erillinen eikä näitä pyyntöjä normaalisti yhdistä mikään toisiinsa. Tätä tilattomuutta täytyy kiertää erilaisilla tavoilla jotta kyetään rakentamaan sovelluksia eikä pelkästään yksinkertaisia www-sivuja. Tällä viikolla opitaan tallentamaan sovelluksen tila lomakkeen sisään piilokenttien avulla (tasot 3 ja 5).
Kaikille tasoille yhteiset vaatimukset:
- Tehtävät on toteutettava python-ohjelmointikielellä CGI-ohjelmina.
- Koodin oleelliset osat on oltava kommentoitu.
- Sivujen sisältämä HTML-koodi tulee olla validia HTML5:sta. Käyttäkää validoinnin apuna web developer toolbarin Tools|Display Page Validation-toimintoa. Epävalidi sivu aiheuttaa tehtävän pisteisiin automaattisesti 2 pisteen vähennyksen.
- Sekä ohjelmakoodin että www-sivun merkistönä pitää olla UTF-8. Varmista, että sivun merkistö toimii kunnolla eli esim. skandinaaviset merkit näkyvät oikein. Testaa Firefoxilla äläkä pelkästään Chromella. WWW-sivun merkistö määrätään Content-type-otsakkeen yhteydessä. Pelkkä Meta-elementti ei riitä.
- Sivun ulkoasumuotoilut on tehtävä CSS:ää käyttäen. CSS:n on oltava myös validia CSS2/3:sta. Kaikki CSS on oltava ulkoisessa CSS-tiedostossa eikä suoraan HTML-dokumentissa.
- Ainoat sallitut Python-kirjastot ovat:
- HTML-koodin seassa ei saa esiintyä SVG-koodia
- Evästeiden ja sessioiden käyttäminen on kiellettyä
- Javascriptin käyttäminen on kiellettyä
- CGI-ohjelma ei saa tallentaa mitään tiedostoihin tai tietokantaan
- CGI-ohjelman täytyy toimia users.jyu.fi-palvelimella. Muille palvelimille sijoitetut vastaukset eivät kelpaa. Älä edes yritä tehdä ohjelmaasi muissa ympäristöissä. Kts. CGI/SSI-tekniikat users.jyu.fi-palvelimella
- CGI-ohjelma on toteutettava Jinja2-templatea käyttäen. CGI-ohjelmassa ei saa esiintyä HTML-koodia vaan kaikki HTML on tuotettava Jinjan templatessa. Jinjan sisältö taas on pidettävä mahdollisimman yksinkertaisena eli kaikki tarkistukset ja muu ohjelmalogiikka on tehtävä cgi-ohjelmassa. kts. MVC-arkkitehtuuri
- Sovellus ei saa kaatua käyttäjän syötteisiin tai merkistövirheisiin
Taso 1
- Kirjoita Python-kielellä CGI-ohjelma, joka luo sivulle halutun kokoisen
mustavalkoisen shakkiruudukon (html-taulukon) (x ruutua korkea ja x ruutua leveä).
- Ohjelmalla voi luoda uuden ruudukon niin monta kertaa kuin haluaa. Uusi ruudukko korvaa aina aiemman ruudukon.
- Ruudukon minimikoko on 8x8 ja maksimikoko on 16x16. Jos kooksi annetaan epäkelpo arvo niin luodaan aina 8x8-kokoinen ruudukko. Ruudukko on luotava tavalla, joka mahdollistaa helposti ja järkevästi paljon suurempienkin luomisen. Ohjelma ei saa kaatua vaikka kooksi yritettäisiin antaa muuta kuin numero.
- Ruutujen koko on oltava 64x64 pikseliä. Koko on määriteltävä CSS:llä. Kaikki CSS on oltava erillisessä CSS-tiedostossa eli CSS:ää ei saa upottaa HTML-koodin sekaan
- Ruudukkoon sijoitetaan siniset ympyrät diagonaalisesti. Ympyräkuvien koko on 50x50 pikseliä.
- Ruudukon alapuolelle kirjoitetaan käyttäjän lomakkeella antama vapaamuotoinen teksti.
- CGI-ohjelman
tuottaman HTML-koodin on oltava validia vaikka käyttäjä syöttäisi lomakkeelle html-koodia. Testaa siis ohjelmasi esim. seuraavanlaisella testisyötteellä:
<td><strong> testi&testi ööää </strong></td>
- CGI-ohjelman
tuottaman HTML-koodin on oltava validia vaikka käyttäjä syöttäisi lomakkeelle html-koodia. Testaa siis ohjelmasi esim. seuraavanlaisella testisyötteellä:
- CGI-ohjelman on toimittava siten, että sitä voidaan käyttää seuraavalla tavalla:
http://users.jyu.fi/~omatunnus/cgi-bin/tiea2080/vt2/vt2.cgi?x=10&teksti=kukku
Edellämainittu loisi suoraan ruudukon, jonka koko on 10x10 ja ruudukon alapuolelle on kirjoitettu sana kukku
- CGI-ohjelma on toteutettava Jinja2-templatea käyttäen. CGI-ohjelmassa ei saa esiintyä HTML-koodia vaan kaikki HTML on tuotettava Jinjan templatessa
- Mallipohja (saa muokata)
Taso 3
Toteuta tason 1 -ohjelma seuraavilla lisäominaisuuksilla:
- Jos taulukon kooksi annetaan epäkelpo arvo (liian suuri, liian pieni tai ei numero) niin taulukkoa ei luoda ollenkaan vaan näytetään koon kysymiseen käytetyn syöttökentän oikealla puolella punaisella tekstillä virheilmoitus: "Syöttämäsi arvo ei kelpaa"
- Taulukkoon sijoitetaan punaisia ja sinisiä nappuloita
kuvan osoittamiin paikkoihin
- Nappulat on sijoiteltava tavalla, joka mahdollistaa helposti isomman tai pienemmän nappulamäärän (useampi rivi ja sarake) sijoittamisen ruudukkoon.
- Tee nappuloista linkkejä joita klikkaamalla kyseinen nappula poistetaan laudalta. Käyttäjä voi siis yksitellen klikkailla kaikki nappulat pois. Ohjelmasi on osattava säilyttää tieto ruudukon tilasta ja ruuduissa esitettävästä tekstistä linkissä ja sen parametreissa
Varmista, että muodostamasi linkit ovat kelvollisia eikä validaattori herjaa niistä. Kts. urllib.quote_plus. Muista testata ykköstasolla annetulla merkkijonolla.
Urlin maksimipituus on noin 2000 merkkiä.. Älä muodosta liian pitkiä osoitteita.
-
Sinun on tehtävä nappuloista linkkejä joihin muodostat sopivia parametreja. Esim.
<a href="ohjelma.cgi?foo=bar&bar=3&foobar=1&foobar=2&foobar=3"><img src="..." alt="..." /></a>
- Pystyäksesi tallentamaan ohjelman tilan urliin on sinun osattava serialisoida jokin pythonin tietorakenne merkkijonoksi. Esim. JSON on hyvä merkkijonotallennusmuoto. Kts. Ostoskori (lähdekoodi, template)
- Uuden pelilaudan nappuloineen voi luoda milloin tahansa
- Muista varmistaa sivusi HTML-koodin validius jokaisessa tilanteessa
Taso 5
Toteuta taso 3:n mukainen CGI-ohjelma seuraavilla laajennuksilla ja muutoksilla:
- Lisää ruudukon yläpuolelle linkki, jolla voi valita sovelluksen tilaksi siirtotilan. Lisää tämän viereen linkki, jolla voi valita poistotilan
- Ohjelman tilaa voi vaihtaa milloin tahansa. Ohjelma muistaa koko ajan missä ruuduissa on nappuloita.
- Jos ohjelmassa on valittu siirtotila niin mahdollista nappuloiden siirtäminen ruudusta toiseen. Hiirellä voi valita siirrettävän nappulan, joka sen jälkeen esitetään vihreänä. Seuraavaksi voi valita tyhjän ruudun johon nappula siirtyy. Jos valitseekin tyhjän ruudun sijaan toisen nappulan niin tämä muuttuu valituksi nappulaksi. Siirrettävä nappula muistaa ja säilyttää alkuperäisen värinsä.
- Poistotilassa ohjelma toimii kuten kolmostasolla
- Lisää sivulle syöttölaatikot joilla voi antaa oman minkä tahansa värikoodin sinisen (#0000ff), punaisen (#ff0000) tai vihreän (#00ff00) tilalle. Jos yrittää antaa kelvottoman värikoodin, niin ohjelma käyttää alkuperäistä väriä. Huom. Käytettyjen svg-kuvien koodia ei saa ympätä suoraan html-koodin sisään vaan kuvia pitää käyttää ulkoisina ja tavallisella img-elementillä. Tarvittavat kuvat on osattava toteuttaa dynaamisesti.
- CGI-ohjelmasi ei saa tallentaa levylle tiedostoja. Kaikki tieto ohjelman tilasta on pidettävä mukana html-koodissa.
- Vinkki: CGI-ohjelmia saa olla useampia kuin yksi. CGI-ohjelma voi tuottaa muutakin kuin HTML-koodia.
Pythonin merkistöongelmat
Peruskaava:
- ohjelmakoodi ja sen merkkijonot UTF-8-merkistössä. Kun kirjoitat koodiin vakiomerkkijonoja niin lisää
niiden eteen u-kirjain, jolloin python tunnistaa ne unicode-merkkijonoiksi eikä asciiksi:
virhe = u"Tämä on virhe"
- html-dokumentin merkistö on myös olta UTF-8 Muista kaikki kohdat missä merkistö ilmoitetaan:
- content-type
- mahdollinen xml-deklaraatio
- mahdollinen meta-elementti
- lomakkeen accept-charset-ominaisuus
- lomakkeelta tulevat kentät pitää dekoodata unicode-merkkijonoiksi esim: form.getfirst("kentta").decode("UTF-8")
- lopullinen tulostettava (webbipalvelimen palauttava) merkkijono enkoodataan UTF-8-merkistöön template.render(tyyli=tyyli).encode("UTF-8")
HTML ja erikoismerkit
Jinja2 hoitaa HTML-erikoismerkkien koodauksen automaattisesti, jos AutoEscape-ominaisuus on päällä.
Erikoismerkit (<, >, &) hoituvat automaattisesti myös jos käyttää dom-rajapintaa. Jos ei käytä niin käyttäjän syötteet on ajettava cgi.escape-funktion läpi. Ei kuitenkaan molempia, koska silloin esim. <-merkki esitetään koodatussa muodossa < eikä <.
Linkkeihin täytyy erikoismerkit koodata vielä erikseen (Percent-encoding), koska linkeissä on omat rajoituksensa. Tämä hoituu urllib.quote_plus-funktiolla. quote_plus edellyttää utf-8-muotoon enkoodattua merkkijonoa.
Käyttäjien kommentit