HTTP-protokollan tilattomuus ja lomakkeet - Viikkotehtävä 2
Tehtävässä on tarkoitus oppia 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 3 -ohjelmointikielellä Flask-ohjelmina users.jyu.fi-palvelimelle. PythonAnywhere-palvelu ei kelpaa.
- Koodin oleelliset osat on oltava kommentoitu.
- Sivujen sisältämä HTML-koodi tulee olla validia XML-yhteensopivaa HTML5:sta eli ns. polyglot HTML5:sta. Käytä valmista pohjaa, jossa on mukana automaattinen validointi. Epävalidi sivu aiheuttaa tehtävän pisteisiin automaattisesti pistevähennyksen.
- Valmiissa pohjassa on mukana myös muutama testi, joilla voit varmentaa sovelluksesi oikean toiminnan. Saat vapaasti parannella testejä ja kirjoittaa niitä uusia. Palauta korjatut ja uudet testit ohjelmakoodisi mukana. Hyvillä testeillä on mahdollista ansaita lisäpisteitä.
- 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 aina riitä.
- Sovelluksen on toimittava moitteetta Firefoxilla sekä Chromella
- 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. Suoraan HTML-dokumentissa ei saa olla CSS-koodia.
- HTML-koodin seassa ei saa esiintyä SVG-koodia
- Evästeiden ja sessioiden käyttäminen on kiellettyä
- Javascriptin käyttäminen on kiellettyä poislukien valmiissa pohjassa olevat tarkistusskriptit
- Ohjelma ei saa tallentaa mitään tiedostoihin tai tietokantaan
- Ohjelman täytyy toimia users.jyu.fi-palvelimella. Muille palvelimille sijoitetut vastaukset eivät kelpaa.
- Ohjelma on toteutettava Jinja2-templatea käyttäen. Python-ohjelmakoodissa ei saa esiintyä HTML-koodia. Kaikki HTML on tuotettava Jinjan templatessa. Jinja-templaten sisältö on pidettävä mahdollisimman yksinkertaisena eli kaikki tarkistukset ja muu ohjelmalogiikka on tehtävä Flask-ohjelmassa Python 3 -kielellä. kts. MVC-arkkitehtuuri
- Sovellus ei saa kaatua käyttäjän syötteisiin tai merkistövirheisiin
- Sovelluksen on käytettävä xhtml-mediatyyppiä eli application/xhtml+xml
- Vinkki: serialisointi
Taso 1
- Tee oma fork valmiista pohjasta, jossa on mukana automaattinen validointi. Muista päivittää versiohallintaa gitlabiin usein.
- Kirjoita Python-kielellä Flask-ohjelma, joka luo sivulle halutun kokoisen
mustavalkoisen shakkiruudukon (html-taulukon) (x ruutua korkea ja x ruutua leveä).
Sovelluksessa on oltava seuraavanlainen lomake:
lomakkeella ei saa olla virheilmoituksia sivulle ensimmäistä kertaa tultaessa
Lomakkeen ulkoasun on vastattava mallikuvaa
Lomakkeen jälkeen samalla sivulla on mustavalkoinen pelilauta (HTML-taulukko), johon sijoitetaan sinisiä pelinappuloita (kuvia) ja pelaajien nimet seuraavalla tavalla:
- Ruudukkoon sijoitetaan siniset pelinappulat diagonaalisesti.
- Ohjelmalla voi luoda uuden ruudukon niin monta kertaa kuin haluaa. Uusi ruudukko korvaa aina aiemman ruudukon. Sivulle ensimmäistä kertaa saavuttaessa lomake on oletusarvojen minimin kokoinen.
- Ruudukon minimikoko on kahdeksan (8) ja maksimikoko on 16. Ruudukko on toteutettava tavalla, joka mahdollistaa helposti minkä tahansa kokoisen ruudukon luomisen.
- Lomake pitää esitäyttää siihen edelliskerralla syötetyillä arvoilla. Ts. jos pelilauta on jo luotu, täytyy siihen käytettyjen tietojen näkyä lomakkeella.
- Jos taulukon kooksi annetaan epäkelpo arvo (liian suuri, liian pieni tai ei numero), näytetään koon kysymiseen käytetyn syöttökentän oikealla puolella punaisella tekstillä virheilmoitus: "Syöttämäsi arvo ei kelpaa". Tätä ei voi toteuttaa vain HTML5-lomake-elementtien tarkistuksilla tai javascriptilla, vaan tarkistus on tehtävä Flask-sovelluksessa ja virheilmoitus on esitettävä html-muodossa. Käytä valmiita testejä oikean toiminnan varmistamiseksi.
- Jos kooksi annetaan epäkelpo arvo, luodaan aina oletusminimin kokoinen ruudukko. Ohjelma ei saa kaatua vaikka kooksi yritettäisiin antaa muuta kuin numero.
- Jos jomman kumman pelaajan nimi jätetään tyhjäksi, esitetään myös siitä virheilmoitus samaan tapaan, kuin taulukon koon yhteydessä
- Pelilaudan yläpuolelle kirjoitetaan lomakkeelle syötetyn pelaaja 1:n nimi.
Pelilaudan alapuolelle kirjoitetaan lomakkeelle syötetyn pelaaja 2:n nimi.
- Ohjelman
tuottaman HTML-koodin on oltava validia vaikka käyttäjä syöttäisi lomakkeelle html-koodia tai muita erikoismerkkejä. Testaa siis ohjelmasi esim. seuraavanlaisella pelaajan nimellä:
<td><strong> testi&testi ööää </td>
- Ohjelman
tuottaman HTML-koodin on oltava validia vaikka käyttäjä syöttäisi lomakkeelle html-koodia tai muita erikoismerkkejä. Testaa siis ohjelmasi esim. seuraavanlaisella pelaajan nimellä:
- Ohjelman ja virheilmoitusten on toimittava siten, että sitä voidaan käyttää myös seuraavalla tavalla:
http://users.jyu.fi/~omatunnus/cgi-bin/ties4080/vt2/vt2.cgi?x=10&pelaaja1=foo&pelaaja2=bar
Edellämainittu loisi suoraan ruudukon, jonka koko on 10x10 ja pelaajien nimet olisivat foo ja bar. Sovellus ei saa myöskään kaatua vaikka vaadittavia parametreja puuttuisi tai esim. ruudukon koko ei ole validi:
http://users.jyu.fi/~omatunnus/cgi-bin/ties4080/vt2/vt2.cgi?x=a
- Ohjelma on toteutettava Jinja2-templatea käyttäen. Ohjelmakoodissa ei saa esiintyä HTML-koodia vaan kaikki HTML on tuotettava Jinjan templatessa. Pyri pitämään kaikki mahdollinen logiikka python-koodissa ja pidä Jinja-koodia mahdollisimman lyhyenä ja yksinkertaisena.
Taso 3
Toteuta tason 1 -ohjelma seuraavilla lisäominaisuuksilla:
- Sovelluksen oletusasetukset määritellään dynaamisella json-tiedostolla, joka
sovelluksen täytyy jokaisella suorituskerralla ladata osoitteesta:
https://europe-west1-ties4080.cloudfunctions.net/vt2_taso1.
Tiedosto on seuraavaa muotoa:
{ "min": 12, "max": 18, "first": "black", "balls": "bottom-to-top", "basecolor": "#7fff00", "selectedcolor": "#00ff00", "movedcolor": "#ff0000" }
- min on ruudukon minimikoko
- max on ruudukon maksimikoko
- first kertoo mikä on ruudukon ensimmäisen ruudun (vasen yläkulma) väri. Se voi olla musta ("black") tai valkoinen ("white"). Ruudukko pitää luoda ensimmäisen ruudun värin perusteella oikein eli joka toinen ruutu on musta ja joka toinen on valkoinen.
- balls kertoo mille akselille siniset pallot piirretään ruudukon sisään. Vaihtoehtoja
on kaksi: vasemmasta ylänurkasta oikeaan alanurkkaan ("top-to-bottom") tai
vasemmasta alanurkasta oikeaan ylänurkkaan ("bottom-to-top")
- Muista asetuksista ei tarvitse kolmostasolla välittää.
Oletusasetukset muuttuvat satunnaisina aikoina
- Ruudukon on aina oltava selainikkunan levyinen. Ruutujen on pysyttävä mittasuhteiltaan neliöinä. Ruudukko saa olla selainikkunaa korkeampi tai matalampi. Sivulle ei saa tulla sivusuuntaista scrollbaria.
- Tee pelilaudan nappulakuvista linkkejä
,
joita klikkaamalla kyseinen nappula poistetaan laudalta. Käyttäjä voi siis
yksitellen klikkailla kaikki nappulat pois.
Ohjelmasi on osattava säilyttää tieto pelilaudalla olevista nappuloista
- Lisää pelilaudan yläpuolelle Undo-painike (ei linkki), jolla voidaan palauttaa
viimeiseksi poistettu pelinappula takaisin paikalleen. Palautettu pelinappula on
poikkeuksellisesti väriltään punainen.
Undo-painike on näkyvissä, kun palautus voidaan tehdä: Jos vähintään yksi pelinappula on poistettu, eikä palautusta ole juuri tehty.
Undo osaa palauttaa vain viimeisimmän poiston
Ohjelmasi on osattava säilyttää tieto ruudukon tilasta ja pelaajien nimistä linkissä ja sen parametreissa. Varmista, että muodostamasi linkki on kelvollinen eikä validaattori herjaa siitä. Muista testata ykköstasolla annetulla merkkijonolla. Käytä esim. JSON-muotoa.
Pystyäksesi tallentamaan ohjelman tilan linkkiin on sinun osattava serialisoida jokin pythonin tietorakenne merkkijonoksi. Esim. JSON on hyvä merkkijonotallennusmuoto. Kts. Ostoskori (lähdekoodi, template)
Urlin maksimipituus on noin 2000 merkkiä.. Älä muodosta liian pitkiä osoitteita. Käytä mahdollisimman tiivistä JSON-muotoa:
json.dumps(objekti, indent=None, separators=(',',':'))
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>
- Lomakkeita voi olla sivulla lukemattoman monta
Taso 5
Toteuta taso 3:n mukainen ohjelma seuraavilla laajennuksilla ja muutoksilla:
- Ruudukon on aina oltava selainikkunan korkuinen tai levyinen sen mukaan kumpi näistä mitoista on pienempi. Ruutujen on pysyttävä mittasuhteiltaan neliöinä. Ruudukon täytyy aina mahtua selainikkunaan, mutta sen täytyy siis olla joko ikkunan levyinen tai korkuinen. Lomake saa rullata sivulta piiloon. Sivulle ei saa tulla sivusuuntaista scrollbaria.
- Lisää ruudukon yläpuolelle linkki , jolla voi valita sovelluksen tilaksi siirtotilan. Lisää tämän viereen linkki , jolla voi valita poistotilan. Oletuksena käytössä on poistotila.
- Ohjelman tilaa voi vaihtaa milloin tahansa. Ohjelma muistaa koko ajan missä ruuduissa on nappuloita.
- Jos ohjelmassa on valittu siirtotila, mahdollista nappuloiden siirtäminen
ruudusta toiseen. Hiirellä voi valita siirrettävän nappulan, joka sen jälkeen
esitetään asetustiedostossa ilmoitetun värisenä. Jos et osaa tätä toteuttaa, käytä
vihreää.
Seuraavaksi voi valita tyhjän ruudun, johon nappula siirtyy. Jos valitseekin
tyhjän ruudun sijaan toisen nappulan, tästä tulee uusi valittu nappula.
Jo valittuna olevaa nappulaa ei voi valita (klikata).
Siirrettävä nappula muistaa ja säilyttää alkuperäisen värinsä.
Javascriptia ei saa käyttää.
Kolmostasolla toteutettu undo-toiminto osaa palauttaa myös siirretyn painikkeen takaisin edelliselle paikalleen.
Laajenna undo-toiminto muistamaan rajaton määrä siirtoja ja poistoja
- Poistotilassa ohjelma toimii kuten kolmostasolla
- Pelinappuloiden väri muuttuu dynaamisesti asetustiedoston mukaan.
- "basecolor": tavallisen nappulan väri
- "selectedcolor": valitun nappulan väri
- "movedcolor": siirretyn nappulan väri
- Ohjelmasi ei saa tallentaa levylle tiedostoja. Kaikki tieto ohjelman tilasta on pidettävä mukana html-koodissa.
- Vinkki: Flask-ohjelma voi tuottaa muutakin kuin HTML-koodia.
Merkistöongelmat
Peruskaava:
- Ohjelmakoodi ja sen merkkijonot on oltava UTF-8-merkistössä.
- html-dokumentin merkistö on myös olta UTF-8 Muista kaikki kohdat
missä merkistö ilmoitetaan:
- content-type-HTTP-otsake (tämä on tärkein)
- mahdollinen xml-deklaraatio
- mahdollinen meta-elementti
- lomakkeen accept-charset-ominaisuus
HTML ja erikoismerkit
Jinja2 hoitaa HTML-erikoismerkkien koodauksen automaattisesti, jos AutoEscape-ominaisuus on päällä. Flask asettaa tämän automaattisesti päälle, jos template-tiedoston nimi päättyy .html, .xml tai .xhtml
Linkkeihin täytyy erikoismerkit koodata vielä erikseen (Percent-encoding), koska linkeissä on omat rajoituksensa. Tämä hoituu urllib.parse.urlencode- tai urllib.parse.quote_plus-funktiolla.
Käyttäjien kommentit