30.01.2015 Views

Programa de la asignatura - docencia de la ETSIT-URJC

Programa de la asignatura - docencia de la ETSIT-URJC

Programa de la asignatura - docencia de la ETSIT-URJC

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Servicios y Aplicaciones en Re<strong>de</strong>s <strong>de</strong> Or<strong>de</strong>nadores<br />

Grado en Sistemas <strong>de</strong> Telecomunicación<br />

<strong>Programa</strong> <strong>de</strong>l curso 2011/2012<br />

Jesús M. González Barahona, Gregorio Robles Martínez<br />

GSyC, Universidad Rey Juan Carlos<br />

19 <strong>de</strong> abril <strong>de</strong> 2012<br />

Índice<br />

1. Datos generales 7<br />

2. Objetivos 8<br />

3. Metodología 8<br />

4. <strong>Programa</strong> <strong>de</strong> teoría 9<br />

4.1. 01 - Presentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

4.1.1. Sesión <strong>de</strong>l 10 <strong>de</strong> enero (1 hora) . . . . . . . . . . . . . . . . 9<br />

4.2. 02 - Conceptos básicos <strong>de</strong> aplicaciones web . . . . . . . . . . . . . . 9<br />

4.2.1. Sesión <strong>de</strong>l 10 <strong>de</strong> enero (1 hora) . . . . . . . . . . . . . . . . 9<br />

4.2.2. Sesión <strong>de</strong>l 17 <strong>de</strong> enero (2 horas) . . . . . . . . . . . . . . . . 9<br />

4.2.3. Sesión <strong>de</strong>l 26 <strong>de</strong> enero (2 horas) . . . . . . . . . . . . . . . . 10<br />

4.2.4. Sesión <strong>de</strong>l 2 <strong>de</strong> febrero (2 horas) . . . . . . . . . . . . . . . . 10<br />

4.2.5. Sesión <strong>de</strong>l 9 <strong>de</strong> febrero . . . . . . . . . . . . . . . . . . . . . 10<br />

4.2.6. Sesión <strong>de</strong>l 16 <strong>de</strong> febrero . . . . . . . . . . . . . . . . . . . . 10<br />

4.2.7. Sesión <strong>de</strong>l 23 <strong>de</strong> febrero (1 hora) . . . . . . . . . . . . . . . . 11<br />

4.3. 03 - Servicios web que interoperan . . . . . . . . . . . . . . . . . . . 11<br />

4.3.1. Sesión <strong>de</strong>l 23 <strong>de</strong> febrero (1 hora) . . . . . . . . . . . . . . . . 11<br />

4.3.2. Sesión <strong>de</strong>l 8 <strong>de</strong> marzo (4 horas) . . . . . . . . . . . . . . . . 11<br />

4.3.3. Sesión <strong>de</strong>l 15 <strong>de</strong> marzo (2 horas) . . . . . . . . . . . . . . . 12<br />

4.3.4. Sesión <strong>de</strong>l 22 <strong>de</strong> marzo (0.5 horas) . . . . . . . . . . . . . . . 12<br />

4.4. 04 - Mo<strong>de</strong>lo-vista-contro<strong>la</strong>dor . . . . . . . . . . . . . . . . . . . . . 12<br />

1


4.4.1. Sesión <strong>de</strong>l 22 <strong>de</strong> marzo (1.5 horas) . . . . . . . . . . . . . . . 12<br />

4.5. 05 - Introducción a XML . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

4.5.1. Sesión <strong>de</strong>l 12 <strong>de</strong> abril (2 horas) . . . . . . . . . . . . . . . . 12<br />

4.5.2. Sesión <strong>de</strong>l 17 <strong>de</strong> abril (1 hora) . . . . . . . . . . . . . . . . . 13<br />

4.6. 06 - Hojas <strong>de</strong> estilo CSS . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

4.6.1. Sesión <strong>de</strong>l 17 <strong>de</strong> abril (1 hora) . . . . . . . . . . . . . . . . . 13<br />

4.7. 07 - Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

5. <strong>Programa</strong> <strong>de</strong> prácticas 14<br />

5.1. P1 - Introducción a Python . . . . . . . . . . . . . . . . . . . . . . 14<br />

5.1.1. Sesión <strong>de</strong>l 12 <strong>de</strong> enero (2 horas) . . . . . . . . . . . . . . . . 14<br />

5.1.2. Sesión <strong>de</strong>l 19 <strong>de</strong> enero (2 horas) . . . . . . . . . . . . . . . . 14<br />

5.1.3. Sesión <strong>de</strong>l 24 <strong>de</strong> enero (2 horas) . . . . . . . . . . . . . . . . 14<br />

5.2. P2 - Aplicaciones web simples . . . . . . . . . . . . . . . . . . . . . 14<br />

5.2.1. Sesión <strong>de</strong>l 31 <strong>de</strong> enero (2 horas) . . . . . . . . . . . . . . . . 15<br />

5.2.2. Sesión <strong>de</strong>l 7 <strong>de</strong> febrero (2 horas) . . . . . . . . . . . . . . . . 15<br />

5.2.3. Sesión <strong>de</strong>l 14 <strong>de</strong> febrero (2 horas) . . . . . . . . . . . . . . . 15<br />

5.3. P3 - Servidores simples <strong>de</strong> contenidos . . . . . . . . . . . . . . . . . 16<br />

5.3.1. Sesión <strong>de</strong>l 21 <strong>de</strong> febrero (2 horas) . . . . . . . . . . . . . . . 16<br />

5.3.2. Sesión <strong>de</strong>l 28 <strong>de</strong> febrero (2 horas) . . . . . . . . . . . . . . . 16<br />

5.3.3. Sesión <strong>de</strong>l 6 <strong>de</strong> marzo (2 horas) . . . . . . . . . . . . . . . . 16<br />

5.4. P4 - Introducción a Django . . . . . . . . . . . . . . . . . . . . . . 17<br />

5.4.1. Sesión <strong>de</strong>l 13 <strong>de</strong> marzo (2 horas) . . . . . . . . . . . . . . . 17<br />

5.4.2. Sesión <strong>de</strong>l 20 <strong>de</strong> marzo . . . . . . . . . . . . . . . . . . . . . 17<br />

5.4.3. Sesión <strong>de</strong>l 27 <strong>de</strong> marzo . . . . . . . . . . . . . . . . . . . . . 17<br />

5.4.4. Sesión <strong>de</strong>l 29 <strong>de</strong> marzo . . . . . . . . . . . . . . . . . . . . . 17<br />

5.4.5. Sesión <strong>de</strong>l 10 <strong>de</strong> abril . . . . . . . . . . . . . . . . . . . . . . 18<br />

6. Ejercicios 02: Sesiones HTTP, Cookies 19<br />

6.1. Última búsqueda . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

6.2. Última búsqueda: números aleatorios o consecutivos . . . . . . . . . 19<br />

6.3. HTTP intercambiado al navegar . . . . . . . . . . . . . . . . . . . . 20<br />

6.4. Cookies en páginas web . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

6.5. Sumador simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

6.6. Sumador simple con varios navegadores . . . . . . . . . . . . . . . . 21<br />

6.7. Sumador simple con rearranques . . . . . . . . . . . . . . . . . . . . 21<br />

6.8. Sumador simple con varios navegadores interca<strong>la</strong>dos . . . . . . . . . 21<br />

6.9. Traza <strong>de</strong> historiales <strong>de</strong> navegación por terceras partes . . . . . . . . 22<br />

6.10. Trackers en páginas web . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

6.11. Entrada en cuenta <strong>de</strong> Moodle . . . . . . . . . . . . . . . . . . . . . 23<br />

6.12. Tese<strong>la</strong>s <strong>de</strong> Google Maps . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

2


7. Ejercicios 03: Servicios web que interoperan 23<br />

7.1. Arquitectura esca<strong>la</strong>ble . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

7.2. Arquitectura distribuida . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

7.3. Sumador simple versión REST . . . . . . . . . . . . . . . . . . . . . 25<br />

7.4. Calcu<strong>la</strong>dora simple versión REST . . . . . . . . . . . . . . . . . . . 25<br />

7.5. Cache <strong>de</strong> contenidos . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

7.6. Cache <strong>de</strong> contenidos anotado . . . . . . . . . . . . . . . . . . . . . . 27<br />

7.7. Gestor <strong>de</strong> contenidos miltilingüe versión REST . . . . . . . . . . . . 29<br />

7.8. Sistema <strong>de</strong> transferencias bancarias . . . . . . . . . . . . . . . . . . 30<br />

7.9. Gestor <strong>de</strong> contenidos multilingüe preferencias <strong>de</strong>l navegador . . . . 30<br />

7.10. Gestor <strong>de</strong> contenidos multilingüe con elección en <strong>la</strong> aplicación . . . 31<br />

7.11. Sistema REST para calcu<strong>la</strong>r Pi . . . . . . . . . . . . . . . . . . . . 32<br />

8. Ejercicios 05: Introducción a XML 32<br />

8.1. Chistes XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

8.2. Titu<strong>la</strong>res <strong>de</strong> BarraPunto . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

8.3. Titu<strong>la</strong>res <strong>de</strong> BarraPunto versión Django . . . . . . . . . . . . . . . 33<br />

8.4. Gestor <strong>de</strong> contenidos con titu<strong>la</strong>res <strong>de</strong> BarraPunto . . . . . . . . . . 33<br />

8.5. Gestor <strong>de</strong> contenidos con titu<strong>la</strong>res <strong>de</strong> BarraPunto versión SQL . . . 34<br />

8.6. Gestor <strong>de</strong> contenidos con titu<strong>la</strong>res <strong>de</strong> BarraPunto versión Django . 34<br />

9. Ejercicios 06: Hojas <strong>de</strong> estilo CSS 34<br />

9.1. Django cms css simple . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />

10.Ejercicios 07: Ajax 35<br />

10.1. SPA Sentences generator . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

10.2. Ajax Sentences generator . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

10.3. Gadget <strong>de</strong> Google . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

10.4. Gadget <strong>de</strong> Google en Django cms . . . . . . . . . . . . . . . . . . . 36<br />

10.5. EzWeb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

10.6. EyeOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

11.Ejercicios P1: Introducción a Python 37<br />

11.1. Uso interactivo <strong>de</strong>l intérprete <strong>de</strong> Python . . . . . . . . . . . . . . . 37<br />

11.2. Ficheros y listas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

11.3. Ficheros, diccionarios y excepciones . . . . . . . . . . . . . . . . . . 38<br />

11.4. Calcu<strong>la</strong>dora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

11.5. Calcu<strong>la</strong>dora orientada a objetos . . . . . . . . . . . . . . . . . . . . 38<br />

3


12.Ejercicios P2: Aplicaciones web simples 39<br />

12.1. Aplicación web ho<strong>la</strong> mundo . . . . . . . . . . . . . . . . . . . . . . 39<br />

12.2. Aplicación web generadora <strong>de</strong> URLs aleatorias . . . . . . . . . . . . 39<br />

12.3. C<strong>la</strong>se servidor <strong>de</strong> aplicaciones . . . . . . . . . . . . . . . . . . . . . 40<br />

12.4. C<strong>la</strong>se servidor <strong>de</strong> aplicaciones, generador <strong>de</strong> urls aleatorias . . . . . 41<br />

12.5. C<strong>la</strong>se servidor <strong>de</strong> aplicaciones, sumador . . . . . . . . . . . . . . . . 41<br />

12.6. C<strong>la</strong>se servidor <strong>de</strong> varias aplicaciones . . . . . . . . . . . . . . . . . . 41<br />

12.7. C<strong>la</strong>se servidor, cuatro aplis . . . . . . . . . . . . . . . . . . . . . . . 41<br />

12.8. Insta<strong>la</strong>ción y prueba <strong>de</strong> Web Developer . . . . . . . . . . . . . . . . 42<br />

13.Ejercicios P3: Servidores simples <strong>de</strong> contenidos 42<br />

13.1. C<strong>la</strong>se contentApp . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />

13.2. Insta<strong>la</strong>ción y prueba <strong>de</strong> Poster . . . . . . . . . . . . . . . . . . . . . 42<br />

13.3. C<strong>la</strong>se contentPutApp . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

13.4. C<strong>la</strong>se contentPostApp . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

13.5. C<strong>la</strong>se contentPersistentApp . . . . . . . . . . . . . . . . . . . . . . 43<br />

13.6. C<strong>la</strong>se contentStorageApp . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

13.7. Gestor <strong>de</strong> contenidos con usuarios . . . . . . . . . . . . . . . . . . . 44<br />

13.8. Gestor <strong>de</strong> contenidos con usuarios, con control estricto <strong>de</strong> actualización<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

14.Ejercicios P4: Introducción a Django 45<br />

14.1. Insta<strong>la</strong>ción <strong>de</strong> Django . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

14.2. Django Intro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

14.3. Django primera aplicación . . . . . . . . . . . . . . . . . . . . . . . 45<br />

14.4. Django calc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

14.5. Django cms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

14.6. Django cms put . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

14.7. Django cms users . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

14.8. Django cms users put . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

14.9. Django cms temp<strong>la</strong>tes . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

14.10.Django cms post . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

14.11.Django feed expan<strong>de</strong>r . . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

14.12.Django feed expan<strong>de</strong>r db . . . . . . . . . . . . . . . . . . . . . . . . 49<br />

15.Ejercicios P6: Aplicaciones web con base <strong>de</strong> datos 50<br />

15.1. Introducción a SQLite3 con Python . . . . . . . . . . . . . . . . . . 50<br />

15.2. Gestor <strong>de</strong> contenidos con base <strong>de</strong> datos . . . . . . . . . . . . . . . . 50<br />

15.3. Gestor <strong>de</strong> contenidos con usuarios, con control estricto <strong>de</strong> actualización<br />

y base <strong>de</strong> datos . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

4


16.Prácticas <strong>de</strong> entrega voluntaria y final (SARO, curso 2011-2012 51<br />

16.1. Práctica 1 (entrega voluntaria) . . . . . . . . . . . . . . . . . . . . . 51<br />

16.1.1. Objetivos <strong>de</strong> <strong>la</strong> práctica . . . . . . . . . . . . . . . . . . . . 51<br />

16.1.2. Conocimientos previos necesarios . . . . . . . . . . . . . . . 51<br />

16.1.3. Ejercicios a realizar . . . . . . . . . . . . . . . . . . . . . . . 51<br />

16.1.4. Entrega <strong>de</strong> <strong>la</strong> práctica . . . . . . . . . . . . . . . . . . . . . 53<br />

16.2. Práctica 2 (entrega voluntaria) . . . . . . . . . . . . . . . . . . . . . 54<br />

16.3. Práctica 3 (entrega voluntaria) . . . . . . . . . . . . . . . . . . . . . 56<br />

17.Práctica final (2012, mayo) 56<br />

17.1. Arquitectura y funcionamiento general . . . . . . . . . . . . . . . . 56<br />

17.2. Esquema básico <strong>de</strong> recursos servidos . . . . . . . . . . . . . . . . . 58<br />

17.3. Funcionalidad mínima . . . . . . . . . . . . . . . . . . . . . . . . . 58<br />

17.4. Funcionalidad optativa . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

17.5. Entrega <strong>de</strong> <strong>la</strong> práctica . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

17.6. Notas y comentarios . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />

18.Ejercicios complementarios <strong>de</strong> varios temas 61<br />

18.1. Ejercicio 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />

18.2. Ejercicio 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

18.3. Ejercicio 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

18.4. Ejercicio 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

19.Prácticas finales <strong>de</strong> cursos pasados 66<br />

19.1. Práctica final (2010, enero) . . . . . . . . . . . . . . . . . . . . . . . 66<br />

19.1.1. Arquitectura y funcionamiento general . . . . . . . . . . . . 66<br />

19.1.2. Funcionalidad mínima . . . . . . . . . . . . . . . . . . . . . 67<br />

19.1.3. Funcionalidad optativa . . . . . . . . . . . . . . . . . . . . . 69<br />

19.1.4. Entrega <strong>de</strong> <strong>la</strong> práctica . . . . . . . . . . . . . . . . . . . . . 69<br />

19.1.5. Notas y comentarios . . . . . . . . . . . . . . . . . . . . . . 70<br />

19.2. Práctica final (2010, junio) . . . . . . . . . . . . . . . . . . . . . . . 70<br />

19.3. Práctica final (2010, diciembre) . . . . . . . . . . . . . . . . . . . . 71<br />

19.3.1. Arquitectura y funcionamiento general . . . . . . . . . . . . 72<br />

19.3.2. Funcionalidad mínima . . . . . . . . . . . . . . . . . . . . . 73<br />

19.3.3. Funcionalidad optativa . . . . . . . . . . . . . . . . . . . . . 74<br />

19.3.4. Entrega <strong>de</strong> <strong>la</strong> práctica . . . . . . . . . . . . . . . . . . . . . 75<br />

19.3.5. Notas y comentarios . . . . . . . . . . . . . . . . . . . . . . 76<br />

19.3.6. Notas <strong>de</strong> ayuda . . . . . . . . . . . . . . . . . . . . . . . . . 77<br />

19.4. Práctica final (2011, junio) . . . . . . . . . . . . . . . . . . . . . . . 78<br />

19.4.1. Arquitectura y funcionamiento general . . . . . . . . . . . . 78<br />

19.4.2. Funcionalidad mínima . . . . . . . . . . . . . . . . . . . . . 79<br />

5


19.4.3. Funcionalidad optativa . . . . . . . . . . . . . . . . . . . . . 81<br />

19.4.4. Entrega <strong>de</strong> <strong>la</strong> práctica . . . . . . . . . . . . . . . . . . . . . 82<br />

19.4.5. Notas y comentarios . . . . . . . . . . . . . . . . . . . . . . 82<br />

19.4.6. Notas <strong>de</strong> ayuda . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

20.Examenes pasados <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> Servicios y Aplicaciones Telemáticas<br />

85<br />

20.1. 2 <strong>de</strong> febrero <strong>de</strong> 2007 . . . . . . . . . . . . . . . . . . . . . . . . . . 85<br />

20.2. 4 <strong>de</strong> septiembre <strong>de</strong> 2007 . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

20.3. 12 <strong>de</strong> febrero <strong>de</strong> 2008 . . . . . . . . . . . . . . . . . . . . . . . . . . 88<br />

20.4. 5 <strong>de</strong> septiembre <strong>de</strong> 2008 . . . . . . . . . . . . . . . . . . . . . . . . 90<br />

20.5. 18 <strong>de</strong> enero <strong>de</strong> 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . 92<br />

20.6. 22 <strong>de</strong> junio <strong>de</strong> 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . 95<br />

20.7. 13 <strong>de</strong> diciembre <strong>de</strong> 2010 . . . . . . . . . . . . . . . . . . . . . . . . 98<br />

20.8. 20 <strong>de</strong> junio <strong>de</strong> 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . 100<br />

20.9. 12 <strong>de</strong> diciembre <strong>de</strong> 2011 . . . . . . . . . . . . . . . . . . . . . . . . 102<br />

21.Evaluación 108<br />

22.Materiales <strong>de</strong> interés para <strong>la</strong> <strong>asignatura</strong> 109<br />

22.1. Material complementario general . . . . . . . . . . . . . . . . . . . 109<br />

22.2. Introducción a Python . . . . . . . . . . . . . . . . . . . . . . . . . 109<br />

22.3. Aplicaciones web mínimas . . . . . . . . . . . . . . . . . . . . . . . 109<br />

22.4. SQL y SQLite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110<br />

6


1. Datos generales<br />

Título: Servicios y Aplicaciones en Re<strong>de</strong>s <strong>de</strong> Or<strong>de</strong>nadores<br />

Titu<strong>la</strong>ción: Grado en Sistemas <strong>de</strong> Telecomunicación<br />

Cuatrimestre: Tercero<br />

Créditos: 6 (3 teóricos, 3 prácticos)<br />

Horas lectivas: 4 horas semanales<br />

Horario: martes, 9:00–11:00<br />

jueves, 9:00–11:00<br />

Profesores: Jesús M. González Barahona<br />

jgb @ gsyc.es<br />

Despacho 003, Biblioteca, Campus <strong>de</strong> Fuen<strong>la</strong>brada<br />

Gregorio Robles Martínez<br />

grex @ gsyc.es<br />

Despacho 110, Departamental III, Campus <strong>de</strong> Fuen<strong>la</strong>brada<br />

7


2. Objetivos<br />

En esta <strong>asignatura</strong> se preten<strong>de</strong> que el alumno obtenga conocimientos <strong>de</strong>tal<strong>la</strong>dos<br />

sobre los servicios y aplicaciones comunes en <strong>la</strong>s re<strong>de</strong>s <strong>de</strong> or<strong>de</strong>nadores, y en particu<strong>la</strong>r<br />

en Internet. Se preten<strong>de</strong> especialmente que conozcan <strong>la</strong>s tecnologías básicas<br />

que los hacen posibles.<br />

3. Metodología<br />

La <strong>asignatura</strong> tiene un enfoque eminentemente práctico, <strong>de</strong> hecho <strong>la</strong> mitad <strong>de</strong><br />

sus créditos se reservan al <strong>de</strong>sarrollo <strong>de</strong> prácticas en los <strong>la</strong>boratorios, incluyendo<br />

una práctica final que se habrá <strong>de</strong> entregar para aprobar <strong>la</strong> <strong>asignatura</strong>. También<br />

existe una componente teórica, para <strong>la</strong> que se utiliza fundamentalmente aprendizaje<br />

basado en resolución <strong>de</strong> problemas. En <strong>la</strong>s c<strong>la</strong>ses teóricas se utilizan, en algunos<br />

casos, transparencias que sirven <strong>de</strong> guión.<br />

Las c<strong>la</strong>ses <strong>de</strong> teoría y <strong>de</strong> prácticas están re<strong>la</strong>cionadas, y se preten<strong>de</strong> que unas<br />

sirvan <strong>de</strong> apoyo a <strong>la</strong>s otras, y viceversa. En el <strong>de</strong>sarrollo diario, pue<strong>de</strong>n encontrarse<br />

componentes teóricos en <strong>la</strong>s c<strong>la</strong>ses prácticas y viceversa, por lo que se tratará <strong>de</strong><br />

que el mayor número posible <strong>de</strong> c<strong>la</strong>ses tengan lugar en el <strong>la</strong>boratorio.<br />

Se usa un sistema <strong>de</strong> apoyo telemático a <strong>la</strong> <strong>docencia</strong> (Moodle) para realizar<br />

activida<strong>de</strong>s complementarias a <strong>la</strong>s presenciales, y para organizar <strong>la</strong> documentación<br />

ofrecida a los alumnos. Los alumnos podrán encontrar el sitio <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> en<br />

http://gsyc.es/moodle<br />

8


4. <strong>Programa</strong> <strong>de</strong> teoría<br />

<strong>Programa</strong> <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> (tentativo)<br />

4.1. 01 - Presentación<br />

4.1.1. Sesión <strong>de</strong>l 10 <strong>de</strong> enero (1 hora)<br />

Presentación: Presentación <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>. Breve introducción y motivación<br />

<strong>de</strong> <strong>la</strong>s aplicaciones web.<br />

Material: Transparencias, tema “Presentación”.<br />

4.2. 02 - Conceptos básicos <strong>de</strong> aplicaciones web<br />

Sesión, mantenimiento <strong>de</strong> estado, persistencia.<br />

4.2.1. Sesión <strong>de</strong>l 10 <strong>de</strong> enero (1 hora)<br />

Ejercicio propuesto (discusión en c<strong>la</strong>se, entrega en el foro): “Última<br />

búsqueda” (ejercicio 6.1)<br />

Se introduce el problema, y se <strong>de</strong>ja un poco <strong>de</strong> tiempo para trabajo por<br />

grupos. Durante este tiempo se mo<strong>de</strong><strong>la</strong>n <strong>la</strong>s interacciones HTTP y se propone<br />

un uso <strong>de</strong> cookies para conseguir <strong>la</strong> funcionalidad requerida. Se discute <strong>la</strong><br />

interacción HTTP en c<strong>la</strong>se.<br />

Discusión y explicación: Almacenamiento en el <strong>la</strong>do <strong>de</strong>l servidor y en el<br />

<strong>la</strong>do <strong>de</strong>l cliente. Re<strong>la</strong>ción entre peticiones HTTP. Cookies como herramienta<br />

para ambas situaciones.<br />

4.2.2. Sesión <strong>de</strong>l 17 <strong>de</strong> enero (2 horas)<br />

Páginas dinámicas (diferentes según cómo y cuándo se invocan). Cómo realizar<br />

sesiones en HTTP. Profundización en el concepto <strong>de</strong> sesión, y técnicas para<br />

conseguir<strong>la</strong>, incluyendo cookies y otros mecanismos.<br />

Discusión y explicación: Almacenamiento en el <strong>la</strong>do <strong>de</strong>l servidor y en el<br />

<strong>la</strong>do <strong>de</strong>l cliente. Re<strong>la</strong>ción entre peticiones HTTP. Cookies como herramienta<br />

para ambas situaciones.<br />

Discusión <strong>de</strong> ejercicio (entrega en el foro): “Última búsqueda: números<br />

aleatorios o consecutivos” (ejercicio 6.2)<br />

Presentación: Cookies<br />

9


Material: Transparencias, tema “Cookies”<br />

4.2.3. Sesión <strong>de</strong>l 26 <strong>de</strong> enero (2 horas)<br />

Discusión: Tres mecanismos básicos para mantenimiento <strong>de</strong> sesión (cookies,<br />

reescritura <strong>de</strong> URLs, campos ocultos en formu<strong>la</strong>rios)<br />

Material: Transparencias, tema “Cookies”<br />

Ejercicio: “HTTP intercambiado al navegar” (ejercicio 6.3)<br />

Ejercicio: “Cookies en páginas web” (ejercicio 6.4)<br />

4.2.4. Sesión <strong>de</strong>l 2 <strong>de</strong> febrero (2 horas)<br />

Ejercicio propuesto (entrega en el foro): “Sumador simple” (ejercicio<br />

6.5)<br />

Ejercicio propuesto (entrega en el foro): “Sumador simple con varios<br />

navegadores” (ejercicio 6.6)<br />

4.2.5. Sesión <strong>de</strong>l 9 <strong>de</strong> febrero<br />

Datos persistentes entre operaciones HTTP diferentes.<br />

Discusión <strong>de</strong> <strong>la</strong> solución al ejercicio: “Sumador simple” (ejercicio 6.5)<br />

Discusión <strong>de</strong> <strong>la</strong> solución al ejercicio: “Sumador simple con varios navegadores”<br />

(ejercicio 6.6)<br />

Discusión <strong>de</strong> ejercicio (entrega en el foro): “Sumador simple con varios<br />

navegadores interca<strong>la</strong>dos” (ejercicio 6.8)<br />

P<strong>la</strong>nteamiento y discusión parcial <strong>de</strong>l ejercicio: “Traza <strong>de</strong> historiales<br />

<strong>de</strong> navegación por terceras partes” (ejercicio 6.9).<br />

4.2.6. Sesión <strong>de</strong>l 16 <strong>de</strong> febrero<br />

Datos persistentes entre operaciones HTTP diferentes. Concepto <strong>de</strong> estado persistente<br />

frente a caídas <strong>de</strong>l servidor.<br />

Ejercicio (discusión y entrega en el foro): “Traza <strong>de</strong> historiales <strong>de</strong><br />

navegación por terceras partes” (ejercicio 6.9).<br />

10


Discusión <strong>de</strong> ejercicio: “Sumador simple con rearranques” (ejercicio 6.7).<br />

Trabajo en grupo. Sólo se preten<strong>de</strong> llegar al pseudocódigo (lo más “estilo<br />

Python” que se pueda).<br />

Ejercicio (entrega en el foro): “Trackers en páginas web” (ejercicio 6.10).<br />

4.2.7. Sesión <strong>de</strong>l 23 <strong>de</strong> febrero (1 hora)<br />

Usos <strong>de</strong> <strong>la</strong>s cookies para autenticación.<br />

Ejercicio (discusión): “Trackers en páginas web” (ejercicio 6.10).<br />

Discusión: Otros usos <strong>de</strong> <strong>la</strong>s cookies. Diferencia entre sesión y autenticación.<br />

Ejercicio (entrega en el foro): “Entrada en cuenta <strong>de</strong> Moodle” (ejercicio<br />

6.11).<br />

4.3. 03 - Servicios web que interoperan<br />

Invocaciones a aplicaciones web <strong>de</strong>s<strong>de</strong> aplicaciones web. Servicios web como un<br />

conjunto <strong>de</strong> aplicaciones que interoperan.<br />

4.3.1. Sesión <strong>de</strong>l 23 <strong>de</strong> febrero (1 hora)<br />

Presentación: Arquitectura REST (introducción)<br />

Material: Transparencias, tema “REST”<br />

Ejercicio (sin entrega): “Tese<strong>la</strong>s <strong>de</strong> Google Maps” (ejercicio 6.12).<br />

4.3.2. Sesión <strong>de</strong>l 8 <strong>de</strong> marzo (4 horas)<br />

Presentación: Arquitectura REST (<strong>de</strong>talle)<br />

Material: Transparencias, tema “REST”<br />

Ejercicio (entrega en el foro): “Calcu<strong>la</strong>dora simple versión REST” (ejercicio<br />

7.4).<br />

Discusión <strong>de</strong> ejercicio (sin entrega): “Cache <strong>de</strong> contenidos” (ejercicio<br />

7.5).<br />

Trabajo en grupos y discusión <strong>de</strong> los <strong>de</strong>talles <strong>de</strong>l ejercicio.<br />

11


4.3.3. Sesión <strong>de</strong>l 15 <strong>de</strong> marzo (2 horas)<br />

Ejercicio (discusión en c<strong>la</strong>se): “Calcu<strong>la</strong>dora simple versión REST” (ejercicio<br />

7.4). Comentarios sobre implementaciones <strong>de</strong> referencia.<br />

Ejercicio (sin entrega): “Cache <strong>de</strong> contenidos anotado” (ejercicio 7.6). Se<br />

recomienda hacer este ejercicio, pero no se pi<strong>de</strong> su entrega en el foro.<br />

4.3.4. Sesión <strong>de</strong>l 22 <strong>de</strong> marzo (0.5 horas)<br />

Ejercicio (discusión en c<strong>la</strong>se): “Sistema REST para calcu<strong>la</strong>r Pi” (ejercicio<br />

7.11)<br />

4.4. 04 - Mo<strong>de</strong>lo-vista-contro<strong>la</strong>dor<br />

4.4.1. Sesión <strong>de</strong>l 22 <strong>de</strong> marzo (1.5 horas)<br />

Presentación: “Mo<strong>de</strong>lo-vista-contro<strong>la</strong>dor”.<br />

Material: Transparencias “Mo<strong>de</strong>lo-vista-contro<strong>la</strong>dor”.<br />

Presentación: “Componentes <strong>de</strong> aplicaciones Django y MVC”. Repaso <strong>de</strong><br />

los componentes principales <strong>de</strong> una aplicación Django y su re<strong>la</strong>ción con el<br />

patrón mo<strong>de</strong>lo-vista-contro<strong>la</strong>dor.<br />

4.5. 05 - Introducción a XML<br />

Uso <strong>de</strong> XML en aplicaciones web.<br />

4.5.1. Sesión <strong>de</strong>l 12 <strong>de</strong> abril (2 horas)<br />

Presentación: “Introducción a XML”.<br />

Introducción a XML, sintáxis básica, formas <strong>de</strong> especificar gramáticas, reconocedores<br />

SAX y DOM. Uso básico <strong>de</strong> HTML DOM <strong>de</strong>s<strong>de</strong> JavaScript.<br />

Material: Transparencias “Introducción a XML”.<br />

Ejercicio: “Chistes XML” (ejercicio 8.1).<br />

Ejercicio (entrega en el foro): “Titu<strong>la</strong>res <strong>de</strong> BarraPunto” (ejercicio 8.2).<br />

12


4.5.2. Sesión <strong>de</strong>l 17 <strong>de</strong> abril (1 hora)<br />

Presentación: “Introducción a XML”.<br />

Usos <strong>de</strong> XML, canales semánticos usando RSS y simi<strong>la</strong>res. Complementos<br />

<strong>de</strong> XML, JSON.<br />

Material: Transparencias “Introducción a XML”.<br />

Demo: Manejo <strong>de</strong> HTML DOM con JavaScript.<br />

Material: Fichero dom.html<br />

Ejercicio (entrega en el foro): “Titu<strong>la</strong>res <strong>de</strong> BarraPunto versión Django”<br />

(ejercicio 8.3).<br />

4.6. 06 - Hojas <strong>de</strong> estilo CSS<br />

4.6.1. Sesión <strong>de</strong>l 17 <strong>de</strong> abril (1 hora)<br />

Hojas <strong>de</strong> estilo CSS, y su uso para manejar <strong>la</strong> apariencia <strong>de</strong> <strong>la</strong>s páginas HTML.<br />

Presentación: “Hojas <strong>de</strong> estilo CSS”. Introducción a CSS. Principales elementos.<br />

Material: Transparencias, tema “CSS”.<br />

Ejercicio (complementario): “Django cms css simple” (ejercicio 9.1).<br />

4.7. 07 - Ajax<br />

13


5. <strong>Programa</strong> <strong>de</strong> prácticas<br />

<strong>Programa</strong> <strong>de</strong> <strong>la</strong>s prácticas <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> (tentativo).<br />

5.1. P1 - Introducción a Python<br />

Introducción al lenguaje <strong>de</strong> programación Python, que se utilizará para <strong>la</strong> realización<br />

<strong>de</strong> <strong>la</strong>s prácticas <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

5.1.1. Sesión <strong>de</strong>l 12 <strong>de</strong> enero (2 horas)<br />

Presentación: “Introducción a Python (parte 1)”<br />

Material: Transparencias “Introducción a Python”<br />

Material: Ejercicios “Introducción a Python” (ejercicio 11.1).<br />

Ejercicio propuesto (entrega en foro): “Calcu<strong>la</strong>dora” (ejercicio 11.4).<br />

5.1.2. Sesión <strong>de</strong>l 19 <strong>de</strong> enero (2 horas)<br />

Presentación: “Introducción a Python (parte 2)”<br />

Material: Transparencias “Introducción a Python”<br />

Material: Ejercicios “Introducción a Python” (ejercicios 11.2 y 11.3).<br />

Ejercicio propuesto (entrega en foro): “Calcu<strong>la</strong>dora orientada a objetos”<br />

(ejercicio 11.5).<br />

5.1.3. Sesión <strong>de</strong>l 24 <strong>de</strong> enero (2 horas)<br />

Presentación: “Introducción a Python (parte 3)”<br />

Material: Transparencias “Introducción a Python”<br />

Ejercicio propuesto (entrega en foro): “Calcu<strong>la</strong>dora” (ejercicio 11.4).<br />

5.2. P2 - Aplicaciones web simples<br />

Construcción <strong>de</strong> aplicaciones web mínimas sobre <strong>la</strong> biblioteca Sockets <strong>de</strong> Python.<br />

14


5.2.1. Sesión <strong>de</strong>l 31 <strong>de</strong> enero (2 horas)<br />

Ejercicio: “Aplicación web ho<strong>la</strong> mundo” (ejercicio 12.1)<br />

Se prsenta el ejercicio, se trata <strong>de</strong> hacer en c<strong>la</strong>se, se muestra <strong>la</strong> solución y<br />

se comenta en c<strong>la</strong>se. Se pi<strong>de</strong> a los alumnos que lo ejecute, lo modifiquen<br />

y se fijen en <strong>la</strong>s cabeceras HTTP enviadas por el servidor que muestra en<br />

pantal<strong>la</strong>. Se prueba entre varios or<strong>de</strong>nadores (servidor en uno, navegador en<br />

otro).<br />

Ejercicio propuesto (entrega en foro): “Aplicación web generadora <strong>de</strong><br />

URLs aleatorias” (ejercicio 12.2)<br />

5.2.2. Sesión <strong>de</strong>l 7 <strong>de</strong> febrero (2 horas)<br />

Explicación <strong>de</strong> ejercicio: “Aplicación web generadora <strong>de</strong> URLs aleatorias”<br />

(ejercicio 12.2)<br />

Ejercicio propuesto: “C<strong>la</strong>se servidor <strong>de</strong> aplicaciones” (ejercicio 12.3)<br />

Explicación <strong>de</strong> <strong>la</strong> estructura general que tienen <strong>la</strong>s aplicaciones web, y fundamentos<br />

<strong>de</strong> cómo esta estructura se pue<strong>de</strong> encapsu<strong>la</strong>r en una c<strong>la</strong>se.<br />

Ejercicio propuesto: “C<strong>la</strong>se servidor <strong>de</strong> aplicaciones, generador <strong>de</strong> URLs<br />

aleatorias” (ejercicio 12.4).<br />

Ejercicio propuesto (entrega en foro): “C<strong>la</strong>se servidor <strong>de</strong> aplicaciones,<br />

sumador” (ejercicio 12.5).<br />

5.2.3. Sesión <strong>de</strong>l 14 <strong>de</strong> febrero (2 horas)<br />

Explicación <strong>de</strong> ejercicio: “C<strong>la</strong>se servidor <strong>de</strong> aplicaciones, sumador” (ejercicio<br />

12.5)<br />

Ejercicio: “Insta<strong>la</strong>ción y prueba <strong>de</strong> Web Developer” (ejercicio 12.8).<br />

Ejercicio propuesto: “C<strong>la</strong>se servidor <strong>de</strong> varias aplicaciones” (ejercicio 12.6)<br />

Explicación <strong>de</strong> <strong>la</strong> estructura principal <strong>de</strong> una c<strong>la</strong>se que gestiona varias aplicaciones<br />

(o varios recursos, cada uno manejado por una aplicación)<br />

Ejercicio propuesto (entrega en foro): “C<strong>la</strong>se servidor, varias aplis”<br />

(ejercicio 12.7).<br />

15


5.3. P3 - Servidores simples <strong>de</strong> contenidos<br />

Construcción <strong>de</strong> algunos servidores <strong>de</strong> contenidos que permitan compren<strong>de</strong>r <strong>la</strong><br />

estructura básica <strong>de</strong> una aplicación web, y <strong>de</strong> cómo implementarlos aprovechando<br />

algunas características <strong>de</strong> Python.<br />

5.3.1. Sesión <strong>de</strong>l 21 <strong>de</strong> febrero (2 horas)<br />

Explicación ejercicio: “C<strong>la</strong>se servidor, varias aplis” (ejercicio 12.7).<br />

Ejercicio: “C<strong>la</strong>se contentApp” (ejercicio 13.1)<br />

Explicación <strong>de</strong> <strong>la</strong> estructura principal <strong>de</strong> una aplicación que sirve contenidos<br />

previamente almacenados.<br />

Ejercicio: “Insta<strong>la</strong>ción y prueba <strong>de</strong> Poster” (ejercicio 13.2).<br />

Ejercicio propuesto (entrega en foro): “C<strong>la</strong>se contentPutApp” (ejercicio<br />

13.3).<br />

5.3.2. Sesión <strong>de</strong>l 28 <strong>de</strong> febrero (2 horas)<br />

Explicación ejercicio propuesto: “C<strong>la</strong>se contentPutApp” (ejercicio 13.3).<br />

Ejercicio: “C<strong>la</strong>se contentPostApp” (ejercicio 13.4).<br />

Ejercicio propuesto (entrega en foro): “Gestor <strong>de</strong> contenidos con usuarios”<br />

(ejercicio 13.7).<br />

5.3.3. Sesión <strong>de</strong>l 6 <strong>de</strong> marzo (2 horas)<br />

Explicación ejercicio propuesto: “Gestor <strong>de</strong> contenidos con usuarios”<br />

(ejercicio 13.7).<br />

Ejercicio: “C<strong>la</strong>se contentPersistentApp” (ejercicio 13.5).<br />

Ejercicio propuesto (entrega en foro): C<strong>la</strong>se “contentStorageApp” (ejercicio<br />

13.6).<br />

Presentación: Enunciado <strong>de</strong> <strong>la</strong> práctica 2 <strong>de</strong> entrega voluntaria (16.2)<br />

16


5.4. P4 - Introducción a Django<br />

5.4.1. Sesión <strong>de</strong>l 13 <strong>de</strong> marzo (2 horas)<br />

Presentación <strong>de</strong> Django como sistema <strong>de</strong> construcción <strong>de</strong> aplicaciones web.<br />

Presentación: Introducción a Django (primera parte)<br />

Ejercicio: “Insta<strong>la</strong>ción <strong>de</strong> Django” (ejercicio 14.1).<br />

Material: Transparencias “Introducción a Django”<br />

5.4.2. Sesión <strong>de</strong>l 20 <strong>de</strong> marzo<br />

Primeros ejercicios con Django.<br />

Presentación: Introducción a Django (segunda parte)<br />

Material: Transparencias “Introducción a Django”<br />

Ejercicio: “Django Primera Aplicación” (ejercicio 14.3).<br />

Ejercicio: “Django Intro” (ejercicio 14.2).<br />

Ejercicio (entrega en el foro): “Django calc” (ejercicio 14.4).<br />

5.4.3. Sesión <strong>de</strong>l 27 <strong>de</strong> marzo<br />

Ejercicio: “Django cms” (ejercicio 14.5).<br />

Ejercicio: “Django cms put” (ejercicio 14.6).<br />

Presentación: Introducción a Django (tercera parte)<br />

Material: Transparencias “Introducción a Django”<br />

Ejercicio: “Django cms users” (ejercicio 14.7).<br />

Ejercicio (entrega en foro): “Django cms users put” (ejercicio 14.8).<br />

Presentación: Enunciado <strong>de</strong> <strong>la</strong> práctica 3 <strong>de</strong> entrega voluntaria (16.3),<br />

5.4.4. Sesión <strong>de</strong>l 29 <strong>de</strong> marzo<br />

POST y formu<strong>la</strong>rios en Django.<br />

Presentación: Introducción a Django (cuarta parte)<br />

Material: Transparencias “Introducción a Django”<br />

17


5.4.5. Sesión <strong>de</strong>l 10 <strong>de</strong> abril<br />

Material: Documentación <strong>de</strong> Django: “Working with forms”<br />

http://docs.djangoproject.com/en/1.2/topics/forms<br />

Ejercicio: “Django cms post” (ejercicio 14.10).<br />

18


6. Ejercicios 02: Sesiones HTTP, Cookies<br />

6.1. Última búsqueda<br />

Enunciado:<br />

¿Cómo mostrar <strong>la</strong> última búsqueda en un buscador Se quiere que un cierto<br />

buscador web muestre a sus usuarios <strong>la</strong> última búsqueda que hicieron en él. Para<br />

ello, se utilizarán cookies. Son relevantes tres interacciones HTTP: <strong>la</strong> primera, en <strong>la</strong><br />

que el navegador pi<strong>de</strong> <strong>la</strong> página HTML con el formu<strong>la</strong>rio <strong>de</strong> búsquedas, <strong>la</strong> segunda,<br />

en <strong>la</strong> que el navegador envía <strong>la</strong> ca<strong>de</strong>na <strong>de</strong> búsqueda que el usuario ha escrito en el<br />

navegador, y <strong>la</strong> tercera, que se realizará en cualquier momento posterior, en <strong>la</strong> que<br />

el navegador vuelve a pedir <strong>la</strong> página con el formu<strong>la</strong>rio <strong>de</strong> búsquedas, que ahora<br />

se recibe anotada con <strong>la</strong> ca<strong>de</strong>na <strong>de</strong> <strong>la</strong> última búsqueda. Se pi<strong>de</strong> indicar dón<strong>de</strong> van<br />

<strong>la</strong>s cookies, cómo son éstas, y cómo solucionan el problema.<br />

Solución:<br />

Se pue<strong>de</strong> hacer utilizando i<strong>de</strong>ntificador <strong>de</strong> sesión en <strong>la</strong>s cookies. Pero también<br />

es posible hacerlo sin que el servidor (el buscador) tenga que almacenar todos los<br />

i<strong>de</strong>ntificadores <strong>de</strong> sesión junto con <strong>la</strong> última búsqueda realizada, lo que tiene varias<br />

ventajas.<br />

Para i<strong>de</strong>ntificador <strong>de</strong> sesión, basta con un número aleatorio gran<strong>de</strong> que se<br />

almacena en <strong>la</strong> cookie. La cookie <strong>la</strong> envía el buscador al navegador en <strong>la</strong> respuesta<br />

al HTTP GET que se realiza para obtener <strong>la</strong> página <strong>de</strong>l buscador. Luego, esa cookie<br />

va en cada POST que hace el navegador (para realizar una nueva búsqueda). Si no<br />

se quiere que el buscador almacena <strong>la</strong> última pregunta para cada sesión, se pue<strong>de</strong><br />

enviar <strong>la</strong> propia búsqueda en <strong>la</strong> cookie.<br />

Discusiones re<strong>la</strong>cionadas:<br />

Ventajas y <strong>de</strong>sventajas <strong>de</strong> utilizar i<strong>de</strong>ntificadores <strong>de</strong> sesión, o <strong>de</strong> almacenar<br />

<strong>la</strong>s preguntas en cookies en el navegador.<br />

¿Serviría el mismo esquema para un servicio <strong>de</strong> banca electrónica (en lugar<br />

<strong>de</strong> “recordar” <strong>la</strong> última pregunta, se quiere recordar qué usuario se autenticó.<br />

Cómo implementarlo usando el i<strong>de</strong>ntificador <strong>de</strong> usuario y <strong>la</strong> contraseña en<br />

<strong>la</strong> cookie. Implicaciones para <strong>la</strong> seguridad. El problema <strong>de</strong> <strong>la</strong> salida <strong>de</strong> <strong>la</strong><br />

sesión.<br />

6.2. Última búsqueda: números aleatorios o consecutivos<br />

Enunciado:<br />

En el ejercicio “Última búsqueda” (ejercicio 6.1) una <strong>de</strong> <strong>la</strong>s soluciones pasa<br />

por usar cookies con i<strong>de</strong>ntificadores <strong>de</strong> sesión. En principio, se han propuesto dos<br />

posibilida<strong>de</strong>s para esos i<strong>de</strong>ntificadores:<br />

19


Números enteros aleatorios sobre un espacio <strong>de</strong> números gran<strong>de</strong> (por ejemplo<br />

entre 0 y 2 128 − 1)<br />

Números enteros consecutivos, comenzando por ejemplo por 0.<br />

Comenta cuál <strong>de</strong> <strong>la</strong>s dos soluciones te parece mejor, y si crees que alguna <strong>de</strong><br />

el<strong>la</strong>s no sirve para resolver el problema. En ambos casos, indica <strong>la</strong>s razones que te<br />

llevan a esa conclusión<br />

6.3. HTTP intercambiado al navegar<br />

Insta<strong>la</strong> el plugin HttpFox para tu navegador Firefox. Este plugin permite ver<br />

con <strong>de</strong>talle <strong>la</strong>s interacciones HTTP <strong>de</strong>l navegador con los sitios web que visita.<br />

Una vez insta<strong>la</strong>do, utilízalo para ver <strong>la</strong> interacción HTTP con el sitio GSyC.es.<br />

Explica porqué se realizan <strong>la</strong>s interacciones que observas, mira sus cabeceras. Visita<br />

varias páginas <strong>de</strong>l sitio y mira qué nuevas interacciones van a apareciendo, cuáles<br />

se repiten y cuáles no.<br />

Referencias<br />

Sitio web <strong>de</strong> HttpFox:<br />

https://addons.mozil<strong>la</strong>.org/en-US/firefox/addon/httpfox/<br />

GSyC.es:<br />

http://gsyc.es<br />

6.4. Cookies en páginas web<br />

Insta<strong>la</strong> el plugin View Cookies para tu navegador Firefox. Este plugin permite<br />

ver con <strong>de</strong>talle <strong>la</strong>s cookies que se reciben con una página web, y eliminar<strong>la</strong>s. Para<br />

ello, una vez insta<strong>la</strong>do, ve a <strong>la</strong> opción “Page Info”, en <strong>la</strong> que verás <strong>la</strong> pestaña<br />

“Cookies”.<br />

Mira <strong>la</strong>s cookies <strong>de</strong> distintas páginas, observa qué ocurre cuando borras algunas.<br />

Por ejemplo, pue<strong>de</strong>n hacerse pruebas con Trabber.com (buscando algunos vuelos,<br />

elgiendo idioma, etc. y borrando luego cookies). Explica qué observas con este o<br />

con otro sitio.<br />

Referencias<br />

Sitio web <strong>de</strong> View Cookies:<br />

http://www.bitstorm.org/extensions/view-cookies/<br />

Trabber.com:<br />

http://trabber.com<br />

20


6.5. Sumador simple<br />

Enunciado:<br />

Construir una aplicación web que suma en dos fases. En <strong>la</strong> primera, invocamos<br />

una URL <strong>de</strong>l tipo http://sumador.edu/5, aportando el primer sumando (el<br />

número que aparece como nombre <strong>de</strong> recurso). En <strong>la</strong> segunda, invocamos una URL<br />

simi<strong>la</strong>r, proporcionando el segundo sumando. La aplicación nos <strong>de</strong>vuelve el resultado<br />

<strong>de</strong> <strong>la</strong> suma. En esta primera versión, suponemos que <strong>la</strong> aplicación es usada<br />

<strong>de</strong>s<strong>de</strong> un solo navegador, y que <strong>la</strong>s URLs siempre le llegan “bien formadas”.<br />

Nota:<br />

Muchos navegadores, cuando se invoca con ellos una URL, <strong>la</strong>nzan un GET para<br />

el<strong>la</strong>, y a continuación uno o varios GET para el recurso “favicon.ico” en el mismo<br />

sitio. Por ello, hace falta tener en cuenta este caso para que funcione <strong>la</strong> aplicación<br />

web con ellos.<br />

6.6. Sumador simple con varios navegadores<br />

Enunciado:<br />

Igual que el ejercicio “Sumador simple” (6.5), pero ahora pue<strong>de</strong> haber varios<br />

navegadores invocando <strong>la</strong> aplicación web. Se supone que los navegadores no se<br />

interfieren (esto es, uno completa una suma antes <strong>de</strong> que otro <strong>la</strong> empiece).<br />

Comentario:<br />

No hacen falta modificaciones al código <strong>de</strong>l ejercicio “Sumador simple” (6.5).<br />

6.7. Sumador simple con rearranques<br />

Enunciado:<br />

Igual que el ejercicio “Sumador simple con varios navegadores” (6.6), pero<br />

ahora <strong>de</strong>s<strong>de</strong> que el navegador inicia <strong>la</strong> suma hasta que <strong>la</strong> completa, pue<strong>de</strong> haberse<br />

caído <strong>la</strong> aplicación web.<br />

Comentario:<br />

La aplicación web tendrá que almacenar su estado en almacenamiento estable.<br />

Hay que <strong>de</strong>tectar cuál es ese estado, y almacenarlo en un fichero, en una base <strong>de</strong><br />

datos, etc.<br />

6.8. Sumador simple con varios navegadores interca<strong>la</strong>dos<br />

Enunciado:<br />

Igual que“Sumador simple con varios navegadores” (6.6), pero ahora un navegador<br />

pue<strong>de</strong> comenzar una suma en cualquier momento, incluyendo momentos en<br />

los que otro navegador no <strong>la</strong> haya terminado.<br />

21


Comentarios:<br />

En una primera versión, se implementa con una cookie simple que incluye el<br />

primer operando, <strong>de</strong> forma que el servidor <strong>de</strong> aplicaciones no tiene que almacenar<br />

los operandos ni <strong>la</strong>s cookies.<br />

En una segunda versión, se utiliza una cookie <strong>de</strong> sesión más clásica, con un<br />

entero aleatorio, y se almacena el estado en un diccionario in<strong>de</strong>xado por ese entero.<br />

6.9. Traza <strong>de</strong> historiales <strong>de</strong> navegación por terceras partes<br />

Cuando un navegador realiza un GET sobre una página web HTML <strong>la</strong>nza a<br />

continuación, <strong>de</strong> forma automática, otras operaciones GET sobre los elementos cargables<br />

automáticamente que contenga esa página, como por ejemplo, <strong>la</strong>s imágenes<br />

empotradas. Cada vez que se realiza uno <strong>de</strong> estos GET, se pue<strong>de</strong>n recibir una o<br />

más cookies <strong>de</strong> los servidores que <strong>la</strong>s sirven (y que en general pue<strong>de</strong>n ser diferentes<br />

<strong>de</strong>l que sirve <strong>la</strong> página HTML).<br />

De esta forma, sirviendo imágenes para diferentes páginas HTML en diferentes<br />

sitios, una tercera parte pue<strong>de</strong> trazar historiales <strong>de</strong> navegación, ligándolos a<br />

i<strong>de</strong>ntificadores únicos. ¿Cómo<br />

A<strong>de</strong>más, si <strong>la</strong> tercera parte en cuestión tiene acceso a información <strong>de</strong> un sitio<br />

web que permita i<strong>de</strong>ntificar i<strong>de</strong>ntida<strong>de</strong>s, esos historiales pue<strong>de</strong>n también ser ligados<br />

a i<strong>de</strong>ntida<strong>de</strong>s. ¿Cómo<br />

Comentarios:<br />

La liga con i<strong>de</strong>ntificadores únicos se pue<strong>de</strong> lograr <strong>de</strong> varias formas, Por ejemplo<br />

se pue<strong>de</strong> incluir en cada página HTML a trazar una imagen con nombre único,<br />

todas servidas por <strong>la</strong> tercera parte. La primera vez que sirve una imagen a un<br />

navegador dado, le envía también una cookie con i<strong>de</strong>ntificador único. Todas <strong>la</strong>s<br />

peticiones <strong>de</strong> imagen que se reciban serán escritas en un historial, junto con el<br />

i<strong>de</strong>ntificador único <strong>de</strong> <strong>la</strong> cookie.<br />

Para po<strong>de</strong>r ligar este historial a una i<strong>de</strong>ntidad, basta con que, en un servidor<br />

que ha i<strong>de</strong>ntificado una i<strong>de</strong>ntidad, sirva una imagen <strong>de</strong> <strong>la</strong> tercera parte con un<br />

nombre que permita posteriormente ligarlo a <strong>la</strong> i<strong>de</strong>ntidad.<br />

6.10. Trackers en páginas web<br />

Insta<strong>la</strong> el plugin Ghostery para tu navegador. Este plugin permite <strong>de</strong>tectar<br />

“trackers”, objetos incluidos en una página web para trazar a quienes <strong>de</strong>scargan<br />

esa página. Utilízalo para encontrar páginas web con muchos trackers. Una vez lo<br />

hayas hecho, indica <strong>la</strong>s dos páginas (<strong>de</strong> sitios distintos) en <strong>la</strong>s que hayas encontrado<br />

más trackers.<br />

Referencias<br />

Sitio web <strong>de</strong> Ghostery: http://www.ghostery.com/<br />

22


6.11. Entrada en cuenta <strong>de</strong> Moodle<br />

Siguel el proceso <strong>de</strong> entrada en tu cuenta Moodle, utilizando el plugin <strong>de</strong> Firefox<br />

HttpFox. I<strong>de</strong>ntifica en qué interacción HTTP se realiza efectivamente <strong>la</strong><br />

entrada, dón<strong>de</strong> va <strong>la</strong> contraseña, qué cookie se recibe y cómo se usa, qué pasa<br />

inmediatamente <strong>de</strong>spués <strong>de</strong> entrar en tu cuenta.<br />

6.12. Tese<strong>la</strong>s <strong>de</strong> Google Maps<br />

En <strong>la</strong> versión <strong>de</strong> Google Maps que sirve imágenes <strong>de</strong> los mapas <strong>de</strong> satélite, los<br />

mapas están divididos en rectángulos (tese<strong>la</strong>s), que se sirven por separado. Busca<br />

cuál es <strong>la</strong> url <strong>de</strong> una <strong>de</strong> esas tese<strong>la</strong>s (por ejemplo, aquel<strong>la</strong> en <strong>la</strong> que se pue<strong>de</strong> ver<br />

el edificio Laboratorios II <strong>de</strong> <strong>la</strong> <strong>URJC</strong> en Fuen<strong>la</strong>brada).<br />

7. Ejercicios 03: Servicios web que interoperan<br />

7.1. Arquitectura esca<strong>la</strong>ble<br />

Enunciado:<br />

Diseñar una arquitectura para una aplicación distribuida que cump<strong>la</strong> <strong>la</strong>s siguientes<br />

condiciones:<br />

Pue<strong>de</strong> ser usada por millones <strong>de</strong> usuarios simultáneamente.<br />

Hay miles <strong>de</strong> equipos <strong>de</strong> <strong>de</strong>sarrollo trabajando sobre el<strong>la</strong>. Entre los equipos<br />

hay poca comunicación pero no <strong>de</strong>ben tener conflictos entre sí.<br />

Cada uno <strong>de</strong> los equipos podrían exten<strong>de</strong>r lo que habían hecho los otros<br />

sin que estos lo sepan y sin que <strong>la</strong> evolución <strong>de</strong> cada sistema rompiera <strong>la</strong><br />

integración.<br />

Comentarios:<br />

Des<strong>de</strong> luego, hay otros sistemas, pero el web, entendido en sentido amplio, es<br />

uno que cumple bien estos requisitos.<br />

7.2. Arquitectura distribuida<br />

Enunciado:<br />

Diseñar una arquitectura para una aplicación distribuida que cump<strong>la</strong> <strong>la</strong>s siguientes<br />

condiciones:<br />

23


Pueda gestionar elementos en mi casa <strong>de</strong>s<strong>de</strong> remoto, en particu<strong>la</strong>r, mi comida.<br />

Por tanto, tendrá que gestionar los alimentos que se encuentran en <strong>la</strong><br />

nevera, <strong>la</strong> <strong>de</strong>spensa, el bol <strong>de</strong> frutas, etc.<br />

Pueda interactuar tanto con máquinas como con humanos<br />

Sea lo más sencil<strong>la</strong> posible<br />

Sea esca<strong>la</strong>ble<br />

Comentarios:<br />

Des<strong>de</strong> luego, hay muchas maneras <strong>de</strong> hacerlo y eso favorecerá el <strong>de</strong>bate.<br />

Una primera i<strong>de</strong>a es mo<strong>de</strong><strong>la</strong>r los elementos como objetos (<strong>la</strong> nevera, los alimentos,<br />

etc.) y hacerlo llegar <strong>de</strong> alguna manera al otro <strong>la</strong>do <strong>de</strong> <strong>la</strong> red, don<strong>de</strong> está mi<br />

portátil (esta es una solución que siguen muchos web services, o incluso CORBA).<br />

Hay que enten<strong>de</strong>r que esto hará que en el <strong>la</strong>do <strong>de</strong>l portátil tengamos que conocer<br />

cómo funcionan los elementos (sus atributos y sus métodos). Es como tener que<br />

apren<strong>de</strong>r el manual <strong>de</strong> instrucciones (los verbos) para cada cacharro que tengamos<br />

en <strong>la</strong> cocina.<br />

Al ver esta solución, nos damos cuenta <strong>de</strong> que contamos en el otro <strong>la</strong>do con<br />

sustantivos. Éstos tienen una localización única, que especificamos mediante una<br />

URL. Asimismo, existe <strong>la</strong> URN, que permite especificar unívocamente un elemento<br />

según su nombre, pero se ha <strong>de</strong> tener en cuenta <strong>de</strong> que pue<strong>de</strong> haber un URN para<br />

muchos elementos (es como el ISBN, que hay uno para toda <strong>la</strong> edición, o sea para<br />

muchos libros). Dado <strong>la</strong> URL localizamos un URN <strong>de</strong> manera unívoca.<br />

Mientas, en el otro <strong>la</strong>do (en el cliente) tendremos un número mínimo <strong>de</strong> acciones<br />

(los verbos). Vemos el primero: GET. Éste no obtiene el sustantivo, sino una<br />

representación <strong>de</strong>l mismo. Los sustantivos son recursos. Y estos recursos pue<strong>de</strong>n<br />

venir expresados <strong>de</strong> varias maneras. Así, por ejemplo, si pedimos manzanas <strong>de</strong>s<strong>de</strong><br />

un portátil <strong>la</strong> representaciónn podría ser una imagen muy <strong>de</strong>tal<strong>la</strong>da; para el móvil,<br />

<strong>la</strong> imagen será más pequeña; y si el que lo pi<strong>de</strong> es una máquina, podría ser un<br />

XML. Vemos los <strong>de</strong>más métodos: PUT, POST y DELETE.<br />

Vistos los métodos discutimos si cambian el estado (vemos que sólo GET no<br />

lo hace) y si el resultado <strong>de</strong> realizar varios consecutivos es igual a hacerlo una vez<br />

(lo que l<strong>la</strong>mamos i<strong>de</strong>mpotencia, vemos que sólo POST no lo es).<br />

Introducimos el concepto <strong>de</strong> elemento y colección <strong>de</strong> elementos (cuando pedimos<br />

una colección, nos da un listado <strong>de</strong> los elementos que contiene; este listado<br />

contiene en<strong>la</strong>ces a los mismos) y qué pasa cuando aplicamos un método a cada<br />

uno. Hacemos especial hincapié en <strong>la</strong> diferencia entre PUT y POST.<br />

Introducimos el concepto <strong>de</strong> REST y sus reg<strong>la</strong>s. Hay varias <strong>la</strong>s hemos visto<br />

ya: URLs, en<strong>la</strong>ces, representaciones y métodos. Nos falta por ver que <strong>la</strong>s comunicaciones<br />

son sin estado. Los recursos pue<strong>de</strong>n tenerlo, pero no <strong>la</strong> comunicación.<br />

24


Discutimos qué significa esto con respecto a lo que hemos visto en <strong>la</strong> <strong>asignatura</strong><br />

hasta ahora, en particu<strong>la</strong>r con respecto a <strong>la</strong>s sesiones (y <strong>la</strong>s cookies).<br />

Finalmente discutimos porque <strong>la</strong> web no es así, si en realidad los diseñadores<br />

<strong>de</strong> HTTP habían diseñado el protocolo para que todo fuera REST. Comentamos<br />

que con los navegadores sólo po<strong>de</strong>mos hacer GETs y POSTs (y contamos que<br />

po<strong>de</strong>mos utilizar los <strong>de</strong>más métodos mediante plug-ins como Poster (ver ejercicio<br />

13.2). Mostramos que, más allá <strong>de</strong> los navegadores, ya estamos en disposición<br />

<strong>de</strong> crear programas para interactuar con servidores REST, <strong>de</strong> manera que po<strong>de</strong>mos<br />

comunicar máquinas entre sí siguiendo estas reg<strong>la</strong>s. Discutimos <strong>la</strong>s ventajas<br />

<strong>de</strong> este enfoque en esos casos.<br />

7.3. Sumador simple versión REST<br />

Enunciado:<br />

Desarrol<strong>la</strong>r una versión RESTful <strong>de</strong> “Sumador simple” (ejercicio 6.5). ¿P<strong>la</strong>ntea<br />

problemas si se usa simultáneamente <strong>de</strong>s<strong>de</strong> varios navegadores ¿P<strong>la</strong>ntea problemas<br />

si se cae el servidor entre dos invocaciones por parte <strong>de</strong>l mismo navegador<br />

Comentarios:<br />

Hay varias formas <strong>de</strong> hacer el diseño, pero por ejemplo, cada sumando podría<br />

ser un recurso, y el resultado obtenerse en un tercero (o bien como respuesta<br />

al actualizar el segundo sumando). Cada suma podría también realizarse en un<br />

espacio <strong>de</strong> nombres <strong>de</strong> recurso distinto (con su propio primer sumando, segundo<br />

sumando y resultado).<br />

7.4. Calcu<strong>la</strong>dora simple versión REST<br />

Enunciado:<br />

Realizar una calcu<strong>la</strong>dora <strong>de</strong> <strong>la</strong>s cuatro operaciones aritméticas básicas (suma,<br />

resta, multiplicación y división), siguiendo los principios REST, a <strong>la</strong> manera <strong>de</strong>l<br />

sumador simple versión REST (ejercicio 7.3).<br />

Comentarios:<br />

Este ejercicio, más que para proponer una solución concreta, está diseñado para<br />

<strong>de</strong>batir sobre <strong>la</strong>s posibles soluciones que se le podrían dar. Por ejemplo, tenemos<br />

primero <strong>la</strong> versiones don<strong>de</strong> se supone un único usuario:<br />

Versión con un recurso por tipo <strong>de</strong> operación (“/suma”, “resta”, etc.). Se<br />

actualiza con PUT, que envía los operandos (ej: 4,5), se consulta con GET,<br />

que <strong>de</strong>vuelve el resultado (ej: 4+5=9).<br />

Versión con un único recurso, “/operacion”. Se actualiza con PUT, que envía<br />

en el cuerpo <strong>la</strong> operación (ej: 4+5), se consulta con GET, que <strong>de</strong>vuelve el<br />

resultado (ej: 4+5=7).<br />

25


Versión actualizando por separado los elementos <strong>de</strong> <strong>la</strong> operación, con un<br />

único recurso “/operacion”. PUT podrá llevar en el cuerpo “Primero: 4” o<br />

“Segundo: 5”, o “Op: +”. Cada uno <strong>de</strong> ellos actualiza el elemento correspondiente<br />

<strong>de</strong> <strong>la</strong> operación. GET <strong>de</strong> ese recurso, <strong>de</strong>vuelve el resultado <strong>de</strong> <strong>la</strong><br />

operación con los elementos que tiene en este momento.<br />

Versión actualizando por separado los elementos <strong>de</strong> <strong>la</strong> operación, con un<br />

único recurso “/operación”. PUT podrá llevar en el cuerpo un número si es<br />

<strong>la</strong> primera o segunda vez que se invoca, un símbolo <strong>de</strong> operación si es <strong>la</strong><br />

tercera. GET dará el resultado si se han especificado todos los elementos <strong>de</strong><br />

<strong>la</strong> operación, error si no. Es “menos REST”, en el sentido que guarda más<br />

estado en el <strong>la</strong>do <strong>de</strong>l servidor. Pero cumple los requisitos generales <strong>de</strong> REST<br />

si consi<strong>de</strong>ramos que le cliente es responsable <strong>de</strong> mantener su estado y saber<br />

en qué fase <strong>de</strong> <strong>la</strong> operación está en cada momento.<br />

Versión don<strong>de</strong> cada elemento se envía con un PUT a un recurso (“/operacion/primeroperando”,<br />

“/operacion/segundooperando”, “/operacion/signo”),<br />

y el resultado se obtiene con “GET /operacion/resultado”. No es REST, porque<br />

el estado <strong>de</strong>l recurso “/operacion/resultado” <strong>de</strong>pen<strong>de</strong> <strong>de</strong>l estado <strong>de</strong> los<br />

otros recursos .<br />

También po<strong>de</strong>mos exten<strong>de</strong>r el diseño a versiones con varios usuarios:<br />

Podría tenerse un i<strong>de</strong>ntificador para cada operación. “POST /operaciones”<br />

podría <strong>de</strong>volver el en<strong>la</strong>ce a una nueva operación creada, como “/operaciones/2af434ad3”.<br />

Cada una <strong>de</strong> estas sumas se comportaría como <strong>la</strong>s “sumas<br />

con un usuario” que se han comentado antes. “DELETE /operaciones/2af434ad3”<br />

<strong>de</strong>struiría una operación.<br />

Material:<br />

simplecalc.py. <strong>Programa</strong> con una posible solución a este ejercicio. Proporciona<br />

cuatro recursos “calcu<strong>la</strong>dora”, uno para cada operación matemática<br />

(suma, resta, multiplicación, división). Cada calcu<strong>la</strong>dora mantiene un estado<br />

(operación matemática) que se actualiza con PUT y se consulta con<br />

GET.<br />

Vi<strong>de</strong>o que muestra el funcionamiento <strong>de</strong> simplecalc.py<br />

http://vimeo.com/31427714<br />

Vi<strong>de</strong>o que <strong>de</strong>scribe el programa simplecalc.py<br />

http://vimeo.com/31430208<br />

26


multicalc.py. <strong>Programa</strong> con otra posible solución a este ejercicio. Proporciona<br />

un recurso para crear calcu<strong>la</strong>doras (mediante POST). Al crear una calcu<strong>la</strong>dora<br />

se especifica <strong>de</strong> qué tipo (operación) es. Cada calcu<strong>la</strong>dora mantiene un<br />

estado (operación matemática) que se actualiza con PUT y se consulta con<br />

GET. Se apoya en <strong>la</strong>s c<strong>la</strong>ses <strong>de</strong>finidas en simplecalc.py para implementar <strong>la</strong>s<br />

calcu<strong>la</strong>doras.<br />

webappmulti.py. C<strong>la</strong>se que proporciona <strong>la</strong> estructura básica para los dos<br />

programas anteriores (c<strong>la</strong>se raíz <strong>de</strong> servicio web, <strong>de</strong> aplis, etc.)<br />

7.5. Cache <strong>de</strong> contenidos<br />

Enunciado:<br />

Vamos a construir una aplicación web que no sólo recibe peticiones <strong>de</strong> un<br />

cliente, sino que también hace peticiones a otros servicios web. El ejercicio consiste<br />

en construir una aplicación que, dada una URL (sin “http://”) como nombre<br />

<strong>de</strong> recurso, <strong>de</strong>vuelve el contenido <strong>de</strong> <strong>la</strong> página correspondiente a esa URL. Esto<br />

es, si se le pi<strong>de</strong> http://localhost:1234/gsyc.es/ <strong>de</strong>vuelve el contenido <strong>de</strong> <strong>la</strong> página<br />

http://gsyc.es/. A<strong>de</strong>más, lo guarda en un diccionario, <strong>de</strong> forma que si se le vuelve<br />

a pedir, lo <strong>de</strong>vuelve directamente <strong>de</strong> ese diccionario. Pue<strong>de</strong> usarse como base<br />

ContentApp, y si se quiere, el módulo estándar <strong>de</strong> Python httplib.<br />

Comentarios:<br />

Pue<strong>de</strong>n discutirse muchos <strong>de</strong>talles <strong>de</strong> esta aplicación. Por ejemplo, cómo gestionar<br />

<strong>la</strong>s cabeceras, y en particu<strong>la</strong>r <strong>la</strong>s cookies. También, cómo saber si <strong>la</strong> página<br />

ha cambiado en el sitio original antes <strong>de</strong> <strong>de</strong>cidir volver a bajar<strong>la</strong> (cabeceras re<strong>la</strong>cionadas<br />

con “cacheable”, peticiones “HEAD” para ver fechas, etc.)<br />

Para <strong>la</strong> implementación <strong>de</strong> <strong>la</strong> aplicación sólo se pi<strong>de</strong> lo más básico: no hay<br />

tratamiento <strong>de</strong> cabeceras, y no se vuelve a bajar el original una vez está en <strong>la</strong><br />

cache.<br />

7.6. Cache <strong>de</strong> contenidos anotado<br />

Enunciado:<br />

Construir una aplicación como “Cache <strong>de</strong> contenidos” (ejercicio 7.5), pero que<br />

anote cada página, en <strong>la</strong> primera línea, con un en<strong>la</strong>ce a <strong>la</strong> página original, y que<br />

incluya también un en<strong>la</strong>ce para “recargar” <strong>la</strong> página (volver<strong>la</strong> a refrescar a partir<br />

<strong>de</strong>l original), otro en<strong>la</strong>ce para ver el HTTP (<strong>de</strong> ida y <strong>de</strong> vuelta) que se intercambió<br />

para conseguir <strong>la</strong> página original, y otro en<strong>la</strong>ce para ver el HTTP <strong>de</strong> <strong>la</strong> consulta<br />

<strong>de</strong>l navegador y <strong>de</strong> <strong>la</strong> respuesta <strong>de</strong>l servidor al pedir esta página.<br />

Comentarios:<br />

27


Téngase en cuenta que por lo tanto cada página que sirva <strong>la</strong> aplicación, a<strong>de</strong>más<br />

<strong>de</strong> los contenidos HTML correspondientes (obtenidos <strong>de</strong> <strong>la</strong> cache o directamente<br />

<strong>de</strong> Internet) tendrá cuatro en<strong>la</strong>ces en <strong>la</strong> primera línea:<br />

En<strong>la</strong>ce a <strong>la</strong> página original.<br />

En<strong>la</strong>ce a un recurso <strong>de</strong> <strong>la</strong> aplicación que permita recargar.<br />

En<strong>la</strong>ce a un recurso <strong>de</strong> <strong>la</strong> aplicación que permita ver el HTTP que se intercambió<br />

con el servidor que tenía <strong>la</strong> página.<br />

En<strong>la</strong>ce a un recurso <strong>de</strong> <strong>la</strong> aplicación que permita ver el HTTP que se intercambió<br />

cuando se cargó en cache esa página.<br />

Estos en<strong>la</strong>ces conviene introducirlos en el cuerpo <strong>de</strong> <strong>la</strong> página HTML que se va<br />

a servir. Así, por ejemplo, si <strong>la</strong> página que se bajó <strong>de</strong> Internet es como sigue:<br />

<br />

... <br />

<br />

Text of the page<br />

<br />

<br />

Debería servirse anotada como sigue:<br />

<br />

... <br />

<br />

Original webpage<br />

Reload<br />

Server-si<strong>de</strong> HTTP<br />

Client-si<strong>de</strong> HTTP<br />

Text of the page<br />

<br />

<br />

Para po<strong>de</strong>r hacer esto, es necesario localizar el elemento < body > en <strong>la</strong> página<br />

HTML que se está anotando. Hay que tener en cuenta que este elemento pue<strong>de</strong><br />

venir tal cual o con atributos, por ejemplo:<br />

<br />

28


Por eso no basta con i<strong>de</strong>ntificar dón<strong>de</strong> está <strong>la</strong> ca<strong>de</strong>na “< body >” en <strong>la</strong> página,<br />

sino que habrá que i<strong>de</strong>ntificar primero dón<strong>de</strong> está “< body” y, a partir <strong>de</strong> ahí, el<br />

cierre <strong>de</strong>l elemento, “>”. Será justo <strong>de</strong>spués <strong>de</strong> ese punto don<strong>de</strong> <strong>de</strong>berán colocarse<br />

<strong>la</strong>s anotaciones. Para encontrar este punto pue<strong>de</strong> usarse el método find <strong>de</strong> <strong>la</strong>s<br />

variables <strong>de</strong> tipo string, o expresiones regu<strong>la</strong>res.<br />

Para que los en<strong>la</strong>ces que se en<strong>la</strong>zan <strong>de</strong>s<strong>de</strong> estas anotaciones funcionen, <strong>la</strong> aplicación<br />

tendrá que aten<strong>de</strong>r a tres nuevos recursos para cada página:<br />

/recurso1: Recarga <strong>de</strong> <strong>la</strong> página en <strong>la</strong> cache.<br />

/recurso2: Devuelve el HTTP con el servidor (que tendrá que estar previamente<br />

almacenado en, por ejemplo, un diccionario).<br />

/recurso3: Devuelve el HTTP con el navegador (que tendrá que estar previamente<br />

almacenado en, por ejemplo, un diccionario).<br />

Naturalmente, cada página necesitará estos tres recursos, por lo tanto lo mejor<br />

será diseñar tres espacios <strong>de</strong> nombres don<strong>de</strong> estén los recursos correspondientes<br />

para cada una <strong>de</strong> <strong>la</strong>s páginas. Por ejemplo, todos los recursos <strong>de</strong> recarga podrían<br />

comenzar por “/reload/”, <strong>de</strong> forma que “/reload/gsyc.es” sería el recurso para<br />

recargar <strong>la</strong> página “http://gsyc.es”.<br />

Para po<strong>de</strong>r almacenar el HTTP con el servidor, es importante darse cuenta <strong>de</strong><br />

que el que se envía al servidor lo produce <strong>la</strong> propia aplicación. Como se usará httplib,<br />

no es posible acce<strong>de</strong>r directamente a lo que se está enviando, pero se pue<strong>de</strong><br />

inferir a partir <strong>de</strong> lo que se indica a httplib. Por lo tanto, cualquier petición HTTP<br />

“razonable” para los parámetros dados será suficiente, aunque no sea exactamente<br />

lo que envíe httplib.<br />

El HTTP que se recibe <strong>de</strong>l servidor habrá que obtenerlo usando httplib. En<br />

particu<strong>la</strong>r, pue<strong>de</strong> encontrarse en el objeto HTTPResponse <strong>de</strong>vuelto por HTTP-<br />

Connection.getresponse().<br />

Para po<strong>de</strong>r almacenar el HTTP con el cliente, es importante darse cuenta<br />

<strong>de</strong> que el que se envía al navegador lo produce <strong>la</strong> propia aplicación, por lo que<br />

basta con almacenarlo antes <strong>de</strong> enviarlo. El que se recibe <strong>de</strong>l navegador habrá que<br />

obtenerlo <strong>de</strong> <strong>la</strong> petición recibida.<br />

7.7. Gestor <strong>de</strong> contenidos miltilingüe versión REST<br />

Enunciado:<br />

Diseño y construcción <strong>de</strong> “Gestor <strong>de</strong> contenidos miltilingüe versión REST”.<br />

Retomamos <strong>la</strong> aplicación ContentApp, pero ahora vamos a proporcionarle una interfaz<br />

multilingüe simple. Para empezar, trabajaremos con español (“es”) e inglés<br />

29


(“en”). Siguiendo <strong>la</strong> filosofía REST, cada recurso lo vamos a tener ahora disponible<br />

en dos URLs distintas, según en qué idioma esté. Los recursos en español<br />

empezarán por “/es/”, y los recursos en inglés por “/en/”. A<strong>de</strong>más, si a un recurso<br />

no se le especifica <strong>de</strong> esta forma en qué idioma está, se servirá en el idioma por<br />

<strong>de</strong>fecto (si está disponible), o en el otro idioma (si no está en el idioma por <strong>de</strong>fecto,<br />

pero sí en el otro). Como siempre, los recursos que no estén disponibles en ningún<br />

idioma producirán un error “Resource not avai<strong>la</strong>ble”.<br />

Comentarios:<br />

Para construir esta aplicación pue<strong>de</strong>s usar dos diccionarios <strong>de</strong> contenidos (uno<br />

para cada idioma), o quizás mejor un diccionario <strong>de</strong> diccionarios, don<strong>de</strong> para cada<br />

recurso tengas como dato un diccionario con los idiomas en que está disponible,<br />

que tienen a su vez como dato <strong>la</strong> página HTML a servir.<br />

7.8. Sistema <strong>de</strong> transferencias bancarias<br />

Enunciado:<br />

Diseñar un sistema RESTful sobre HTTP fiable para realizar una transferencia<br />

bancaria vía HTTP.<br />

Debe po<strong>de</strong>r confirmarse que <strong>la</strong> transferencia ha sido realizada.<br />

Debe po<strong>de</strong>r prevenirse que <strong>la</strong> transferencia se haga más <strong>de</strong> una vez.<br />

Datos <strong>de</strong> <strong>la</strong> transferencia: cuenta origen, cuenta <strong>de</strong>stino, cantidad.<br />

También <strong>de</strong>be po<strong>de</strong>r consultarse el saldo <strong>de</strong> <strong>la</strong> cuenta (datos: cuenta)<br />

En un segundo escenario, pue<strong>de</strong> suponerse todo lo anterior, pero consi<strong>de</strong>rando<br />

que hay una contraseña que protege el acceso a operaciones sobre una<br />

cuenta data (una contraseña por cuenta), tanto transferencias como consultas<br />

<strong>de</strong> saldo .<br />

Indica el esquema <strong>de</strong> recursos (urls) que ofrecerá <strong>la</strong> aplicación, y los verbos<br />

(comandos) HTTP que aceptará para cada uno, y con qué semántica.<br />

7.9. Gestor <strong>de</strong> contenidos multilingüe preferencias <strong>de</strong>l navegador<br />

Enunciado:<br />

Diseñar y construir <strong>la</strong> aplicación web “Gestor <strong>de</strong> contenidos multilingüe preferencias<br />

<strong>de</strong>l navegador”. En <strong>la</strong> aplicación “Gestor <strong>de</strong> contenidos multilingüe versión<br />

REST” (ejercicio 7.7) se especificaban como parte <strong>de</strong>l nombre e recurso el idioma<br />

30


en que se quiere recibir un recurso. Pero el navegador tiene habitualmente una<br />

forma <strong>de</strong> especificar en qué idioma quieres recibir <strong>la</strong>s páginas cuando están disponibles<br />

en varios. Para ver cómo funciona esto, prueba a cambiar tus preferencias<br />

idiomáticas en Firefox, y consulta <strong>la</strong> página http://<strong>de</strong>bian.org.<br />

Implementa una aplicación web que sea como <strong>la</strong> anterior, pero que a<strong>de</strong>más,<br />

haga caso <strong>de</strong> <strong>la</strong>s preferencias <strong>de</strong>l navegador con que <strong>la</strong> invoca, al menos para el<br />

caso <strong>de</strong> los idiomas “es” y “en”.<br />

Material complementario:<br />

Descripción <strong>de</strong> “Accept-Language” en <strong>la</strong> especificación <strong>de</strong> HTTP (RFC 2616)<br />

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4<br />

Comentario:<br />

¿Qué recibe el servidor para po<strong>de</strong>r hacer <strong>la</strong> selección <strong>de</strong> idioma Utiliza una<br />

<strong>de</strong> tus aplicaciones para ver lo que le llega al servidor. Verás que lo que utiliza<br />

el navegador para indicar <strong>la</strong>s preferencias idiomáticas <strong>de</strong>l usuario es <strong>la</strong> cabecera<br />

“Accept-Language”<br />

7.10. Gestor <strong>de</strong> contenidos multilingüe con elección en <strong>la</strong><br />

aplicación<br />

Enunciado:<br />

Diseñar y construir <strong>la</strong> aplicación web “Gestor <strong>de</strong> contenidos multilingüe con<br />

elección en <strong>la</strong> aplicación”. Ahora vamos a construir un servidor <strong>de</strong> contenidos<br />

multilingüe que a<strong>de</strong>más <strong>de</strong> los dos mecanismos anteriores (interfaz REST y preferencias<br />

<strong>de</strong>l navegador, ejercicios 7.7 y 7.9) permita que el usuario elija el idioma<br />

específicamente en <strong>la</strong> propia aplicación.<br />

Para ello, el gestor <strong>de</strong> contenidos aten<strong>de</strong>rá a peticiones GET sobre recursos<br />

<strong>de</strong> <strong>la</strong> forma “/<strong>la</strong>nguage/es” (para indicar que se quieren recibir <strong>la</strong>s páginas en<br />

español), “/<strong>la</strong>nguage/en” (para indicar que se quieren recibir <strong>la</strong>s páginas en inglés)<br />

o “<strong>la</strong>nguage/browser” (para indicar que se quieren recibir <strong>la</strong>s páginas en el idioma<br />

que indique <strong>la</strong>s preferencias <strong>de</strong>l navegador).<br />

El mecanismo <strong>de</strong> especificación <strong>de</strong> idioma mediante nombre <strong>de</strong> recurso (“/en”<br />

o /es”) tendrá prece<strong>de</strong>ncia sobre el mecanismo <strong>de</strong> especificación en <strong>la</strong> aplicación,<br />

y éste sobre el <strong>de</strong> preferencias <strong>de</strong>l navegador.<br />

Cada página incluirá, a<strong>de</strong>más <strong>de</strong>l contenido en el idioma especificado, una<br />

lista (con en<strong>la</strong>ces) <strong>de</strong> los idiomas en que está disponible esa página, y una lista<br />

(con en<strong>la</strong>ces) <strong>de</strong> los idiomas que se pue<strong>de</strong>n elegir en <strong>la</strong> aplicación. Por ejemplo,<br />

si estamos consultando una página en español que está disponible también en<br />

inglés, veremos un en<strong>la</strong>ce “This page in English” que apuntará a <strong>la</strong> URL REST<br />

<strong>de</strong> esa página en inglés. A<strong>de</strong>más, habrá en<strong>la</strong>ces a “Ver páginas preferentemente<br />

31


en español” (que apuntará al recurso /<strong>la</strong>nguage/es), “See pages preferently in<br />

English” (que apuntará al recurso /<strong>la</strong>nguage/en) y “Ver páginas según preferencias<br />

<strong>de</strong>l navegador” (que apuntará a /<strong>la</strong>nguage/browser).<br />

Comentario:<br />

Para implementar <strong>la</strong> elección especificándolo en <strong>la</strong> propia aplicación se podrán<br />

usar cookies, aunque no haya sistema <strong>de</strong> cuentas en <strong>la</strong> aplicación, como es el caso.<br />

7.11. Sistema REST para calcu<strong>la</strong>r Pi<br />

Enunciado:<br />

Diseñar un sistema RESTful sobre HTTP que permita calcu<strong>la</strong>r el número pi<br />

como una operación asíncrona.<br />

El usuario solicita el comienzo <strong>de</strong>l cálculo indicando el número <strong>de</strong> <strong>de</strong>cimales<br />

<strong>de</strong>seado<br />

El usuario <strong>de</strong>be po<strong>de</strong>r consultar a partir <strong>de</strong> ese momento el estado <strong>de</strong>l cálculo<br />

Indica el esquema <strong>de</strong> recursos (urls) que ofrecerá <strong>la</strong> aplicación, y los verbos<br />

(comandos) HTTP que aceptará para cada uno, y con qué semántica.<br />

Hágnase dos versiones: en <strong>la</strong> primera, se supone que hay un sólo usuario (navegador)<br />

<strong>de</strong>l sistema. En <strong>la</strong> segunda, pue<strong>de</strong> haber varios, pero no simultáneamente:<br />

si un usuario solicita el comienzo <strong>de</strong>l cálculo mientras hay otro cálculo en curso,<br />

le <strong>de</strong>vuelve un mensaje <strong>de</strong> error.<br />

8. Ejercicios 05: Introducción a XML<br />

8.1. Chistes XML<br />

Enunciado:<br />

Estudia y modifica el programa xml-parser-jokes.py (que funciona con el fichero<br />

jokes.xml), hasta que entiendas los rudimentos <strong>de</strong>l manejo <strong>de</strong> reconocedores SAX<br />

con Python.<br />

Material:<br />

jokes.xml. Fichero XML con <strong>de</strong>scripciones <strong>de</strong> chistes.<br />

xml-parser-jokes.py. <strong>Programa</strong> que lee el fichero anterior, y usando un parser<br />

SAX lo reconoce y muestra en pantal<strong>la</strong> el contenido <strong>de</strong> los chistes.<br />

32


8.2. Titu<strong>la</strong>res <strong>de</strong> BarraPunto<br />

Enunciado:<br />

Descargar el fichero RSS <strong>de</strong> BarraPunto 1 , y construir un programa que produzca<br />

como salida sus titu<strong>la</strong>res en una página HTML. Si se carga esa página en<br />

un navegador, picando sobre un titu<strong>la</strong>r, el navegador <strong>de</strong>berá cargar <strong>la</strong> página <strong>de</strong><br />

BarraPunto con <strong>la</strong> noticia correspondiente. Como base pue<strong>de</strong> usarse lo aprendido<br />

estudiando los programas xml-parser-jokes.py y xml-parser-barrapunto.py.<br />

Material:<br />

http://barrapunto.com/in<strong>de</strong>x.rss: url <strong>de</strong>l fichero RSS <strong>de</strong> BarraPunto.<br />

xml-parser-barrapunto.py: <strong>Programa</strong> que muestre en pantal<strong>la</strong> los titu<strong>la</strong>res y<br />

<strong>la</strong>s URLs que se <strong>de</strong>scriben en el fichero barrapunto.rss.<br />

barrapunto.rss: Fichero con el contenido <strong>de</strong>l canal RSS <strong>de</strong> BarraPunto en un<br />

momento dado.<br />

8.3. Titu<strong>la</strong>res <strong>de</strong> BarraPunto versión Django<br />

Enunciado:<br />

Reliza una aplicación Django que sirva, se le pida <strong>la</strong> url que se le pida, el<br />

listado <strong>de</strong> noticias que contenga en ese momento el fichero RSS <strong>de</strong> BarraPunto 2<br />

(ver ejercicio 8.2).<br />

Para ello, cada vez que se pida una página cualquiera a <strong>la</strong> aplicación, esta<br />

bajará <strong>de</strong> BarraPunto el fichero RSS, analizará sus contenidos, y <strong>de</strong>volverá una<br />

página HTML con sus titu<strong>la</strong>res. Cuando se vea esa página en un navegador, picando<br />

sobre un titu<strong>la</strong>r el navegador <strong>de</strong>berá cargar <strong>la</strong> página <strong>de</strong> BarraPunto con <strong>la</strong><br />

noticia correspondiente.<br />

8.4. Gestor <strong>de</strong> contenidos con titu<strong>la</strong>res <strong>de</strong> BarraPunto<br />

Enunciado:<br />

Partiendo <strong>de</strong> contentApp (“Gestor <strong>de</strong> contenidos”, ejercicio 13.1), realiza contentAppBarraPunto.<br />

Esta versión <strong>de</strong>volverá, para cada recurso para el cuál tenga<br />

un contenido asociado en el diccionario <strong>de</strong> contenidos, una página que incluirá el<br />

contenido en cuestión, y los titu<strong>la</strong>res <strong>de</strong> BarraPunto (para cada uno, título y URL).<br />

Para ello, podéis hacer por un <strong>la</strong>do una aplicación que sirva para bajar el<br />

canal RSS <strong>de</strong> <strong>la</strong> portada <strong>de</strong> BarraPunto, y lo almacene en un objeto persistente<br />

(usando, por ejemplo, Shelve). Por otro <strong>la</strong>do, contentBarraPuntoApp leerá, antes<br />

1 http://barrapunto.com<br />

2 http://barrapunto.com<br />

33


<strong>de</strong> <strong>de</strong>volver una página, ese objeto, y utilizará sus datos para componer esa página<br />

a <strong>de</strong>volver<br />

8.5. Gestor <strong>de</strong> contenidos con titu<strong>la</strong>res <strong>de</strong> BarraPunto versión<br />

SQL<br />

Enunciado:<br />

Realiza contentDBAppBarraPuntoSQL, con <strong>la</strong> misma funcionalidad que contentAppBarraPunto<br />

(ejercicio 8.4), pero usando una base <strong>de</strong> datos SQLite en lugar<br />

<strong>de</strong> un diccionario persistente gestionado con Shelve.<br />

8.6. Gestor <strong>de</strong> contenidos con titu<strong>la</strong>res <strong>de</strong> BarraPunto versión<br />

Django<br />

Enunciado:<br />

Realiza una aplicación Django con <strong>la</strong> misma funcionalidad que contentDBApp-<br />

BarraPuntSQL (ejercicio 8.5), pero usando el entorno <strong>de</strong> <strong>de</strong>sarrollo Django.<br />

Para reutilizar código, pue<strong>de</strong>s partir <strong>de</strong> “Django cms” (ejercicio 14.5) o “Django<br />

cms put” (ejercicio 14.6).<br />

En particu<strong>la</strong>r, pue<strong>de</strong>s implementar <strong>la</strong> consulta a BarraPunto <strong>de</strong> una <strong>de</strong> <strong>la</strong>s<br />

siguientes formas:<br />

Cada vez que se pida un recurso, se mostrará el contenido asociado a él,<br />

anotado con los titu<strong>la</strong>res <strong>de</strong> BarraPunto, que se <strong>de</strong>scargarán (vía canal RSS)<br />

en ese mismo momento.<br />

Habrá un recurso especial, “/update”, que se usará para actualizar una tab<strong>la</strong><br />

con los contenidos <strong>de</strong> BarraPunto. Cuando se invoque este recurso, se bajarán<br />

los titu<strong>la</strong>res (vía canal RSS) <strong>de</strong> BarraPunto, y se almacenarán en una<br />

tab<strong>la</strong> en <strong>la</strong> base <strong>de</strong> datos que mantiene Django. Cada vez que se pida cualquier<br />

otro recurso, se mostrará el contenido asociado a él, anotado con los<br />

titu<strong>la</strong>res <strong>de</strong> BarraPunto, que se extraerán <strong>de</strong> esa tab<strong>la</strong>, sin volver a pedirlos<br />

a BarraPunto.<br />

Basta con mostrar por ejemplo los últimos tres o cinco titu<strong>la</strong>res <strong>de</strong> BarraPunto<br />

(cada uno como un en<strong>la</strong>ce a <strong>la</strong> URL correspondiente).<br />

9. Ejercicios 06: Hojas <strong>de</strong> estilo CSS<br />

9.1. Django cms css simple<br />

Enunciado:<br />

34


Crea una hoja <strong>de</strong> estilo en <strong>la</strong> URL “/css/main.css” para manejar <strong>la</strong> apariencia<br />

<strong>de</strong> <strong>la</strong> página “/about” en “Django cms put” (ejercicio 14.6). La hoja tendrá el<br />

siguiente contenido:<br />

body {<br />

margin: 10px 20% 50px 70px;<br />

font-family: sans-serif;<br />

color: b<strong>la</strong>ck;<br />

background: white;<br />

}<br />

La página “/about” tendrá el contenido que estimes conveniente. Ambos contenidos<br />

(el <strong>de</strong> “/about” y el <strong>de</strong> “/css/main.css”) se subirán al gestor <strong>de</strong> contenidos<br />

mediante un PUT, igual que cualquier otro contenido.<br />

10. Ejercicios 07: Ajax<br />

Ejercicios con Ajax y tecnologías re<strong>la</strong>cionadas.<br />

10.1. SPA Sentences generator<br />

Enunciado:<br />

Prueba el fichero sentences generator.html, que incluye una aplicación SPA<br />

simple que genera frases <strong>de</strong> forma aleatoria, a partir <strong>de</strong> componentes <strong>de</strong> tres listas<br />

<strong>de</strong> fragmentos <strong>de</strong> frases. En particu<strong>la</strong>r, observa dón<strong>de</strong> se obtiene una referencia al<br />

nodo <strong>de</strong>l árbol DOM don<strong>de</strong> se quiere colocar <strong>la</strong> frase, y cómo se manipu<strong>la</strong> éste<br />

árbol para colocar<strong>la</strong> ahí, una vez está generada.<br />

Una vez lo hayas entendido, modifícalo para que en lugar <strong>de</strong> usar tres fragmentos<br />

para cada frase, use cuatro, cogiendo cada uno, aleatoriamente, <strong>de</strong> una lista <strong>de</strong><br />

fragmentos.<br />

Material:<br />

sentences generator.html: Aplicación SPA que muestra frases componiendo<br />

fragmentos.<br />

10.2. Ajax Sentences generator<br />

Enunciado:<br />

Construye una aplicación con funcionalidad simi<strong>la</strong>r a “SPA Sentences generator”<br />

(ejercicio 10.1), pero realizada mediante una aplicación Ajax que pi<strong>de</strong> los<br />

datos a un servidor implementado en Django.<br />

35


El servidor aten<strong>de</strong>rá GET sobre los recursos /first, /second y /third, dando<br />

para cada uno <strong>de</strong> ellos <strong>la</strong> parte correspondiente (primera, segunda o tercera) <strong>de</strong><br />

una frase, <strong>de</strong>volviendo un fragmento <strong>de</strong> texto aleatorio <strong>de</strong> una lista con fragmentos<br />

que tenga para cada uno <strong>de</strong> ellos (esto es, habrá una lista para los “primeros”<br />

fragmentos, otra para los segundos, y otra para los terceros).<br />

La aplicación Ajax solicitará los tres fragmentos que necesita, y los compondrá<br />

mostrando <strong>la</strong> frase resultante, <strong>de</strong> forma simi<strong>la</strong>r a como lo hace <strong>la</strong> aplicación<br />

“SPA Sentences generator”.<br />

Material:<br />

words provi<strong>de</strong>r.tar.gz: Proyecto Django que sirve como servidor que proporciona<br />

fragmentos <strong>de</strong> frases para <strong>la</strong> aplicación Ajax anterior. Incluye apps/sentences generator.ht<br />

aplicación Ajax que muestra frases componiendo fragmentos que obtiene <strong>de</strong><br />

un sitio web, utilizando l<strong>la</strong>madas HTTP síncronas, y apps/async sentences generator.html<br />

(simi<strong>la</strong>r, pero con l<strong>la</strong>madas asíncronas).<br />

10.3. Gadget <strong>de</strong> Google<br />

Enunciado:<br />

Inclusión <strong>de</strong> un gadget <strong>de</strong> Google, a<strong>de</strong>cuadamente configurado, en una página<br />

HTML estática.<br />

Referencias:<br />

http://www.google.com/ig/directorysynd=open<br />

10.4. Gadget <strong>de</strong> Google en Django cms<br />

Enunciado:<br />

Crear una versión <strong>de</strong>l gestor <strong>de</strong> contenidos Django (Django cms, ejercicio 14.5)<br />

con un gadget <strong>de</strong> Google en cada página (el mismo en todas el<strong>la</strong>s).<br />

10.5. EzWeb<br />

Enunciado:<br />

Abrir una cuenta en el sitio <strong>de</strong> EzWeb, y crear allí un nuevo espacio <strong>de</strong> trabajo<br />

don<strong>de</strong> se conecten algunos gadgets.<br />

Referencia:<br />

http://ezweb.tid.es<br />

10.6. EyeOS<br />

Enunciado:<br />

36


Abrir una cuenta en el sitio <strong>de</strong> EyeOS, y visitar el entorno que proporciona.<br />

Referencia:<br />

http://www.eyeos.org/<br />

11. Ejercicios P1: Introducción a Python<br />

Estos ejercicios preten<strong>de</strong>n ayudar a conocer el lenguaje <strong>de</strong> programación Python.<br />

Los ejercicios suponen que previamente el alumno se ha documentado sobre el<br />

lenguaje, usando <strong>la</strong>s referencias ofrecidas en c<strong>la</strong>se, u otras equivalentes que pueda<br />

preferir.<br />

Aunque es fácil encontrar soluciones a los ejercicios propuestos, se recomienda<br />

al alumno que realice por si mismo todos ellos.<br />

El primer ejercicio has <strong>de</strong> hacerlo directamente en el intérprete <strong>de</strong> Python<br />

(invocándolo sin un programa fuente como argumento). Para los <strong>de</strong>más, pue<strong>de</strong>s<br />

usar un editor (Emacs, gedit, o el que quieras) )o un IDE (Eclipse con el módulo<br />

PyDev, o el que quieras).<br />

11.1. Uso interactivo <strong>de</strong>l intérprete <strong>de</strong> Python<br />

Enunciado:<br />

Invoca el intérprete <strong>de</strong> Python <strong>de</strong>s<strong>de</strong> <strong>la</strong> shell. Crea <strong>la</strong>s siguientes variables:<br />

un entero<br />

una ca<strong>de</strong>na <strong>de</strong> caracteres con tu nombre<br />

una lista con cinco nombres <strong>de</strong> persona<br />

un diccionario <strong>de</strong> cuatro entradas que utilice como l<strong>la</strong>ve el nombre <strong>de</strong> uno<br />

<strong>de</strong> tus amigos y como valor su número <strong>de</strong> móvil<br />

Comprueba con <strong>la</strong> sentencia print nombre_variable que todo lo que has<br />

hecho es correcto.<br />

Fíjate en particu<strong>la</strong>r que <strong>la</strong> lista mantiene el or<strong>de</strong>n que has introducido, mientras<br />

el diccionario no lo hace. Prueba a mostrar los distintos elementos <strong>de</strong> <strong>la</strong> lista y <strong>de</strong>l<br />

diccionario con print.<br />

11.2. Ficheros y listas<br />

Enunciado:<br />

37


Crea un script en Python que abra el fichero /etc/passwd, tome todas sus<br />

líneas en una lista <strong>de</strong> Python e imprima, para cada i<strong>de</strong>ntificador <strong>de</strong> usuario, <strong>la</strong><br />

shell que utiliza.<br />

Imprime también el número <strong>de</strong> usuarios que hay en esta máquina. Utiliza para<br />

ello un método asociado a <strong>la</strong> lista, no un contador <strong>de</strong> <strong>la</strong> iteración.<br />

11.3. Ficheros, diccionarios y excepciones<br />

Enunciado:<br />

Modifica el script anterior, <strong>de</strong> manera que en vez <strong>de</strong> imprimir para cada i<strong>de</strong>ntificador<br />

<strong>de</strong> usuario el tipo <strong>de</strong> shell que utiliza, lo introduzca en un diccionario.<br />

Una vez introducidos todos, imprime por pantal<strong>la</strong> los valores para el usuario ’root’<br />

y para el usuario ’imaginario’. El segundo produce un error, porque no existe.<br />

¿Sabrías evitarlo mediante el uso <strong>de</strong> excepciones<br />

11.4. Calcu<strong>la</strong>dora<br />

Enunciado:<br />

Crea un programa que sirva <strong>de</strong> calcu<strong>la</strong>dora y que incluya <strong>la</strong>s funciones básicas<br />

(sumar, restar, multiplicar y dividir). El programa ha <strong>de</strong> po<strong>de</strong>r ejecutarse <strong>de</strong>s<strong>de</strong> <strong>la</strong><br />

línea <strong>de</strong> comandos <strong>de</strong> <strong>la</strong> siguiente manera: python calcu<strong>la</strong>dora.py funcion operador1<br />

operador1. No olvi<strong>de</strong>s capturar <strong>la</strong>s excepciones.<br />

11.5. Calcu<strong>la</strong>dora orientada a objetos<br />

Enunciado:<br />

Crea un programa en Python que implemente una calcu<strong>la</strong>dora orientada a<br />

objetos. El programa ha <strong>de</strong> implementar <strong>la</strong>s siguientes operaciones: suma, resta,<br />

multiplicación y división. Se imprimirá el resultado por pantal<strong>la</strong>. Los operandos y<br />

el operador se tomarán <strong>de</strong> <strong>la</strong> línea <strong>de</strong> comandos (utilizando sys.argv <strong>de</strong>l módulo<br />

sys, mediante ïmport sys”).<br />

38


12. Ejercicios P2: Aplicaciones web simples<br />

Estos ejercicios presentan al alumno unas pocas aplicaciones web que, aunque<br />

<strong>de</strong> funcionalidad mínima, van introduciendo algunos conceptos fundamentales.<br />

12.1. Aplicación web ho<strong>la</strong> mundo<br />

Enunciado:<br />

Construir una aplicación web, en Python, que muestre en el navegador “Ho<strong>la</strong><br />

mundo” cuando sea invocada. La aplicación usará únicamente <strong>la</strong> biblioteca socket.<br />

Construir <strong>la</strong> aplicación <strong>de</strong> <strong>la</strong> forma más simple posible, mientras proporcione<br />

correctamente <strong>la</strong> funcionalidad indicada.<br />

Motivación:<br />

Este ejercicio sirve para construir el primer ejemplo <strong>de</strong> aplicación web. Con el<strong>la</strong><br />

se muestra ya <strong>la</strong> estructura típica genérica <strong>de</strong> una aplicación web: inicialización y<br />

bucle <strong>de</strong> atención a peticiones (a su vez dividido en recepción y análisis <strong>de</strong> petición,<br />

proceso y lógica y <strong>de</strong> aplicación, y respuesta). Todo está muy simplificado: no se<br />

hace análisis <strong>de</strong> <strong>la</strong> petición, porque se consi<strong>de</strong>ra que todo vale, no se realiza proceso<br />

<strong>de</strong> <strong>la</strong> petición, porque siempre se hace lo mismo, y <strong>la</strong> respuesta es en realidad<br />

mínima.<br />

Aunque no se usará mucho en <strong>la</strong> <strong>asignatura</strong> <strong>la</strong> biblioteca socket (pues trabajaremos<br />

a niveles <strong>de</strong> abstracción superiores), esta práctica sirve para ayudar a enten<strong>de</strong>r<br />

los <strong>de</strong>talles que normalmente oculta un marco <strong>de</strong> <strong>de</strong>sarrollo <strong>de</strong> aplicaciones web.<br />

La práctica también sirve para introducir el esquema típico <strong>de</strong> prueba (carga<br />

<strong>de</strong> <strong>la</strong> página principal <strong>de</strong> <strong>la</strong> aplicación con un navegador, colocación en un puerto<br />

TCP <strong>de</strong> usuario, etc.).<br />

Material:<br />

Se ofrecen dos soluciones. La más simple es:<br />

02-aplicaciones-web-simples/servidor-http-simple.py<br />

La otra, que permite conexiones <strong>de</strong>s<strong>de</strong> fuera <strong>de</strong> <strong>la</strong> máquina huesped, y es capaz<br />

<strong>de</strong> reusar el puerto <strong>de</strong> forma que se pue<strong>de</strong> rearrancar en cuanto muere es:<br />

02-aplicaciones-web-simples/servidor-http-simple-2.py<br />

12.2. Aplicación web generadora <strong>de</strong> URLs aleatorias<br />

Enunciado:<br />

Construcción <strong>de</strong> una aplicación web que <strong>de</strong>vuelve URLs aleatorias. Cada vez<br />

que os conectéis al servidor, aparezca en el navegador “Ho<strong>la</strong>. ¿Quieres mas”,<br />

don<strong>de</strong> “Quieres mas” es un en<strong>la</strong>ce a una URL aleatoria bajo localhost:1234<br />

(esto es, por ejemplo, http://localhost:1234/324324234). Esa URL ha <strong>de</strong> ser<br />

distinta cada vez que un navegador se conecte a <strong>la</strong> aplicación.<br />

39


Motivación:<br />

Explorar una aplicación web como extensión muy simple <strong>de</strong> “Aplicación web<br />

ho<strong>la</strong> mundo”.<br />

12.3. C<strong>la</strong>se servidor <strong>de</strong> aplicaciones<br />

Enunciado:<br />

Reescribe el programa “Aplicación web ho<strong>la</strong> mundo” usando c<strong>la</strong>ses, y reutilizándo<strong>la</strong>s,<br />

haz otro que <strong>de</strong>vuelva “Adiós mundo cruel” en lugar <strong>de</strong> “Ho<strong>la</strong> mundo”.<br />

Para ello, <strong>de</strong>fine una c<strong>la</strong>se webApp que sirva como c<strong>la</strong>se raíz, que al especializar<br />

permitirá tener aplicaciones web que hagan distintas cosas (en nuestro caso,<br />

ho<strong>la</strong>App y adiosApp).<br />

Esa c<strong>la</strong>se webApp tendrá al menos:<br />

Un método Analyze (o Parse), que <strong>de</strong>volverá un objeto con lo que ha analizado<br />

<strong>de</strong> <strong>la</strong> petición recibida <strong>de</strong>l navegador (en el caso más simple, el objeto<br />

tendrá un nombre <strong>de</strong> recurso)<br />

Un método Compute (o Process), que recibirá como argumento el objeto<br />

con lo analizado por el método anterior, y <strong>de</strong>volverá una lista con el código<br />

resultante (por ejemplo, “200 OK”) y <strong>la</strong> página HTML a <strong>de</strong>volver<br />

Código para inicializar una instancia que incluya el bucle general <strong>de</strong> atención<br />

a clientes, y <strong>la</strong> gestión <strong>de</strong> sockets necesaria para que funcione.<br />

Una vez <strong>la</strong> c<strong>la</strong>se webApp esté <strong>de</strong>finida, en otro módulo <strong>de</strong>fine <strong>la</strong> c<strong>la</strong>se ho<strong>la</strong>App,<br />

hija <strong>de</strong> <strong>la</strong> anterior, que especializará los métodos Parse y Process como haga falta<br />

para implementar el “Ho<strong>la</strong> mundo”.<br />

El código __main__ <strong>de</strong> ese módulo instanciará un objeto <strong>de</strong> c<strong>la</strong>se ho<strong>la</strong>App, con<br />

lo que tendremos una aplicación “Ho<strong>la</strong> mundo” funcionando.<br />

Luego, haz lo mismo para adiosApp.<br />

Conviene que en el módulo don<strong>de</strong> se <strong>de</strong>fina <strong>la</strong> c<strong>la</strong>se webApp se incluya también<br />

código para, en caso <strong>de</strong> ser l<strong>la</strong>mado como programa principal, se cree un objeto <strong>de</strong><br />

ese tipo, y se ejecute una aplicación web simple.<br />

Motivación:<br />

Explorar el sistema <strong>de</strong> c<strong>la</strong>ses <strong>de</strong> Python, y a <strong>la</strong> vez construir <strong>la</strong> estructura<br />

básica <strong>de</strong> una aplicación web con un esquema muy simi<strong>la</strong>r al que proporciona el<br />

módulo Python SocketServer<br />

40


12.4. C<strong>la</strong>se servidor <strong>de</strong> aplicaciones, generador <strong>de</strong> urls aleatorias<br />

Enunciado:<br />

Realizar el servidor especificado en el ejercicio “Aplicación web generadora <strong>de</strong><br />

URLs aleatorias” (ejercicio 12.2) utilizando el esquema <strong>de</strong> c<strong>la</strong>ses <strong>de</strong>finido en el<br />

ejercicio “C<strong>la</strong>se servidor <strong>de</strong> aplicaciones” (ejercicio 12.3).<br />

12.5. C<strong>la</strong>se servidor <strong>de</strong> aplicaciones, sumador<br />

Enunciado:<br />

Realizar el servidor especificado en el ejercicio “Sumador simple” (ejercicio 6.5)<br />

utilizando el esquema <strong>de</strong> c<strong>la</strong>ses <strong>de</strong>finido en el ejercicio “C<strong>la</strong>se servidor <strong>de</strong> aplicaciones”<br />

(ejercicio 12.3).<br />

12.6. C<strong>la</strong>se servidor <strong>de</strong> varias aplicaciones<br />

Enunciado:<br />

Realizar una nueva c<strong>la</strong>se, simi<strong>la</strong>r a <strong>la</strong> que se construyó en el ejercicio “C<strong>la</strong>se<br />

servidor <strong>de</strong> aplicaciones” (ejercicio 12.3), pero preparada para servir varias aplicaciones<br />

(aplis). Cada apli se activará cuando se invoquen recursos que comiencen<br />

por un cierto prefijo.<br />

Cada una <strong>de</strong> estas aplis será a su vez una instancia <strong>de</strong> una c<strong>la</strong>se con origen<br />

en una básica con los dos métodos “parse” y “process”, con <strong>la</strong> misma funcionalidad<br />

que tenían en “C<strong>la</strong>se servidor <strong>de</strong> aplicaciones”. Por lo tanto, para tener una<br />

cierta apli, se exten<strong>de</strong>rá <strong>la</strong> jerarquía <strong>de</strong> c<strong>la</strong>ses para aplis con una nueva c<strong>la</strong>se, que<br />

re<strong>de</strong>finirá “parse” y “process” según <strong>la</strong> semántica <strong>de</strong> <strong>la</strong> apli.<br />

Para especificar qué apli se activará cuando llegue una invocación a un nombre<br />

<strong>de</strong> recurso, se creará un diccionario don<strong>de</strong> para cada prefijo se indicará <strong>la</strong> instancia<br />

<strong>de</strong> apli a invocar. Este diccionario se pasará como parámetro al instanciar <strong>la</strong> c<strong>la</strong>se<br />

que sirve varias aplicaciones.<br />

12.7. C<strong>la</strong>se servidor, cuatro aplis<br />

Enunciado:<br />

Utilizando <strong>la</strong> c<strong>la</strong>se creada para “C<strong>la</strong>se servidor <strong>de</strong> varias aplicaciones” (ejercicio<br />

12.6), crea una una aplicación web con varias aplis:<br />

Si se invocan recursos que comiencen por “/ho<strong>la</strong>”, se <strong>de</strong>vuelve una página<br />

HTML en <strong>la</strong> que se vea el texto “Ho<strong>la</strong>”.<br />

41


Si se invocan recursos que comiencen por “/adios”, se <strong>de</strong>vuelve una página<br />

HTML en <strong>la</strong> que se vea el texto “Adiós”.<br />

Si se invocan recursos que comiencen por “/suma/”, se proporciona <strong>la</strong> funcionalidad<br />

<strong>de</strong> “Sumador simple” (ejercicio 6.5), esperando que los sumandos<br />

se incluyan justo a continuación <strong>de</strong> “/suma/”.<br />

Si se invocan recursos que comiencen por “/aleat/”, se proporciona <strong>la</strong> funcionalidad<br />

<strong>de</strong> “Aplicación web generadora <strong>de</strong> URLs aleatorias” (ejercicio 12.2).<br />

12.8. Insta<strong>la</strong>ción y prueba <strong>de</strong> Web Developer<br />

Enunciado:<br />

Insta<strong>la</strong>ción y prueba <strong>de</strong> Web Developer, add-on <strong>de</strong> Firefox<br />

Referencias:<br />

Web Developer Firefox add-on:<br />

https://addons.mozil<strong>la</strong>.org/en-US/firefox/addon/60/<br />

13. Ejercicios P3: Servidores simples <strong>de</strong> contenidos<br />

Construcción <strong>de</strong> algunos servidores <strong>de</strong> contenidos que permitan compren<strong>de</strong>r <strong>la</strong><br />

estructura básica <strong>de</strong> una aplicación web, y <strong>de</strong> cómo implementarlos aprovechando<br />

algunas características <strong>de</strong> Python.<br />

13.1. C<strong>la</strong>se contentApp<br />

Enunciado:<br />

Esta c<strong>la</strong>se, basada en el esquema <strong>de</strong> c<strong>la</strong>ses <strong>de</strong>finido en el ejercicio “C<strong>la</strong>se servidor<br />

<strong>de</strong> aplicaciones” (ejercicio 12.3), sirve el contenido almacenado en un diccionario<br />

Python. La c<strong>la</strong>ve <strong>de</strong>l diccionario es el nombre <strong>de</strong> recurso a servir, y el valor es el<br />

cuerpo <strong>de</strong> <strong>la</strong> página HTML correspondiente a ese recurso.<br />

13.2. Insta<strong>la</strong>ción y prueba <strong>de</strong> Poster<br />

Enunciado:<br />

Insta<strong>la</strong>ción y prueba <strong>de</strong> Poster, add-on <strong>de</strong> Firefox<br />

Referencias:<br />

Poster Firefox add-on:<br />

https://addons.mozil<strong>la</strong>.org/en-US/firefox/addon/2691/<br />

42


13.3. C<strong>la</strong>se contentPutApp<br />

Enunciado:<br />

Construcción <strong>de</strong> <strong>la</strong> c<strong>la</strong>se “contentPutApp”, simi<strong>la</strong>r a contentApp (ejercicio 13.1).<br />

En este caso, <strong>la</strong> c<strong>la</strong>se permite <strong>la</strong> actualización <strong>de</strong>l contenido mediante peticiones<br />

HTTP PUT. Para probar<strong>la</strong>, se pue<strong>de</strong> usar el add-on <strong>de</strong> Firefox l<strong>la</strong>mado “Poster”.<br />

La c<strong>la</strong>se será minimalista, basta con que funcione con “Poster”.<br />

Opcionalmente, pue<strong>de</strong> trabajarse en conseguir que un servidor construido con <strong>la</strong><br />

c<strong>la</strong>se anterior funcione con Bluefish. Bluefish es un editor <strong>de</strong> contenidos, que pue<strong>de</strong><br />

cargar una página especificando su URL, y que una vez modificada, pue<strong>de</strong> enviar<strong>la</strong>,<br />

usando PUT, <strong>de</strong> nuevo a <strong>la</strong> misma URL. Aunque esto es exactamente lo que<br />

espera <strong>la</strong> c<strong>la</strong>se “contentPutApp”, hay algunas peculiarida<strong>de</strong>s <strong>de</strong> funcionamiento<br />

<strong>de</strong> Bluefish que hacen que probablemente <strong>la</strong> c<strong>la</strong>se haya <strong>de</strong> ser modificada para que<br />

funcione correctamente con esta herramienta.<br />

13.4. C<strong>la</strong>se contentPostApp<br />

Enunciado:<br />

Construcción <strong>de</strong> <strong>la</strong> c<strong>la</strong>se “contentPostApp”, simi<strong>la</strong>r a contentApp (ejercicio 13.1).<br />

En este caso, <strong>la</strong> c<strong>la</strong>se permite <strong>la</strong> actualización <strong>de</strong>l contenido mediante peticiones<br />

HTTP POST. Cuando se reciba un GET pidiendo cualquier recurso, se buscará en<br />

el diccionario <strong>de</strong> contenidos, y si existe, se servirá. En cualquier caso (exista o no<br />

exista el contenido en cuestión) se servirá en <strong>la</strong> misma página un formu<strong>la</strong>rio que<br />

permitirá actualizar el contenido <strong>de</strong>l diccionario (o crear una nueva entrada, si no<br />

existía) mediante un POST.<br />

Referencias:<br />

Forms in HTML (HTML 4.01 Specification by W3C):<br />

http://www.w3.org/TR/html4/interact/forms.html<br />

13.5. C<strong>la</strong>se contentPersistentApp<br />

Enunciado:<br />

Construcción <strong>de</strong> <strong>la</strong> c<strong>la</strong>se contentPersistentApp, simi<strong>la</strong>r a contentPutApp (ejercicio<br />

13.3), pero incluyendo almacenamiento <strong>de</strong>l diccionario con los contenidos en<br />

almacenamiento persistente, <strong>de</strong> forma que <strong>la</strong> aplicación mantenga estado al recuperarse<br />

<strong>de</strong>spués <strong>de</strong> una caída. Para mantener estado, pue<strong>de</strong> usarse el módulo<br />

“Shelve” <strong>de</strong> Python, que permite almacenar y recuperar objetos en ficheros.<br />

Opcionalmente, pue<strong>de</strong> usarse en otra versión el módulo “dbm” <strong>de</strong> Python, que<br />

sirve también para gestionar diccionarios persistentes, pero con más limitaciones.<br />

43


13.6. C<strong>la</strong>se contentStorageApp<br />

Enunciado:<br />

Construcción <strong>de</strong> <strong>la</strong> c<strong>la</strong>se contentStorageApp simi<strong>la</strong>r a contentPersistentApp,<br />

pero que use un objeto <strong>de</strong> c<strong>la</strong>se permanentContentStore para almacenar el estado<br />

que ha <strong>de</strong> sobrevivir a caídas <strong>de</strong> <strong>la</strong> aplicación. Esta c<strong>la</strong>se mantendrá variables<br />

internas con el estado a salvaguardar persistentemente, y métodos para consultar<br />

y actualizar los valores <strong>de</strong> ese estado.<br />

13.7. Gestor <strong>de</strong> contenidos con usuarios<br />

Enunciado:<br />

Construye <strong>la</strong> c<strong>la</strong>se contentAppUsers, que amplía el gestor <strong>de</strong> contenidos que<br />

estamos construyendo (c<strong>la</strong>se contentStorageApp, ejercicio 13.6) con el concepto <strong>de</strong><br />

usuarios registrados.<br />

Cada usuario registrado tendrá un nombre y una contraseña (que pue<strong>de</strong>s almacenar<br />

por ejemplo en un diccionario), y sólo si se ha mostrado al sistema que se es<br />

usuario registrado se podrá cambiar contenido <strong>de</strong>l sitio (mediante un PUT). Para<br />

mostrar que se es usuario <strong>de</strong>l sistema, se hará un GET a un recurso <strong>de</strong> <strong>la</strong> forma<br />

“/login,usuario,contraseña”, don<strong>de</strong> “usuario” y “contraseña” son el nombre <strong>de</strong> un<br />

usuario y su contraseña. A partir <strong>de</strong> ese momento, el sistema reconocerá que los<br />

accesos <strong>de</strong>s<strong>de</strong> el mismo navegador son <strong>de</strong> ese usuario.<br />

13.8. Gestor <strong>de</strong> contenidos con usuarios, con control estricto<br />

<strong>de</strong> actualización<br />

Enunciado:<br />

Construye <strong>la</strong> c<strong>la</strong>se contentAppUsersStrict, que implemente <strong>la</strong> misma funcionalidad<br />

<strong>de</strong> contentAppUsers (ejercicio 13.7), pero que a<strong>de</strong>más controle que sólo<br />

actualiza un contenido quien lo creó. En otras pa<strong>la</strong>bras, cuando <strong>la</strong> aplicación recibe<br />

un PUT, se comprueba que el recurso no existe, y en ese caso, si lo está subiendo<br />

un usuario autenticado, se crea. Pero si el recurso existe, sólo lo actualiza si el usuario<br />

que está invocando el PUT es el mismo que creó el recurso. Para implementar<br />

esta funcionalidad pue<strong>de</strong>s utilizar un diccionario que “recuer<strong>de</strong>” quien creó cada<br />

recurso, o añadir, a los datos <strong>de</strong>l diccionario <strong>de</strong> contenidos (don<strong>de</strong> sólo había <strong>la</strong><br />

página HTML para el recurso en cuestión) un nuevo elemento (por ejemplo, usando<br />

una lista): el usuario que creó el recurso.<br />

44


14. Ejercicios P4: Introducción a Django<br />

14.1. Insta<strong>la</strong>ción <strong>de</strong> Django<br />

Enunciado:<br />

Insta<strong>la</strong> <strong>la</strong> versión <strong>de</strong> Django que utilizaremos en prácticas.<br />

Comentarios:<br />

Utilizaremos <strong>la</strong> versión Django-1.3.1.<br />

Material:<br />

Descarga <strong>de</strong> Django: http://www.djangoproject.com/download/<br />

Transparencias “Introducción a Django”<br />

14.2. Django Intro<br />

Enunciado:<br />

Realización <strong>de</strong> un proyecto Django <strong>de</strong> prueba (myproject), siguiendo el ejemplo<br />

<strong>de</strong> <strong>la</strong>s transparencias “Introducción a Django”. Creación <strong>de</strong> <strong>la</strong>s tab<strong>la</strong>s <strong>de</strong> su base<br />

<strong>de</strong> datos, con Django, y consulta <strong>de</strong> <strong>la</strong> base <strong>de</strong> datos creada con sqlitebrowser.<br />

Material:<br />

myproject.tar.gz: Ejemplo <strong>de</strong> solución <strong>de</strong>l ejercicio “Django intro”.<br />

14.3. Django primera aplicación<br />

Enunciado:<br />

Realización <strong>de</strong> una aplicación Django que haga cualquier cosa, aún sin usar<br />

datos en almacenamiento estable. Por ejemplo, pue<strong>de</strong> simplemente respon<strong>de</strong>r a<br />

ciertos recursos con páginas HTML <strong>de</strong>finidas en el propio programa (en el correspondiente<br />

fichero views.py).<br />

14.4. Django calc<br />

Enunciado:<br />

Realizar una calcu<strong>la</strong>dora con Django. Esta calcu<strong>la</strong>dora respon<strong>de</strong>rá a URLs<br />

<strong>de</strong> <strong>la</strong> forma “/num1+num2”, “/num1*num2”, “/num1-num2”, “/num1/num2”,<br />

realizando <strong>la</strong>s operaciones correspondientes, y <strong>de</strong>volviendo error “Not Found” para<br />

<strong>la</strong>s <strong>de</strong>más.<br />

Material:<br />

calc.tar.gz: Ejemplo <strong>de</strong> solución <strong>de</strong>l ejercicio “Django calc”<br />

45


14.5. Django cms<br />

Enunciado:<br />

Realizar una sistema <strong>de</strong> gestión <strong>de</strong> contenidos muy simple con Django. Correspon<strong>de</strong>rá<br />

con <strong>la</strong> funcionalidad <strong>de</strong> “contentApp” (ejercicio 13.1), almacenando los<br />

contenidos en una base <strong>de</strong> datos.<br />

Material:<br />

cms.tar.gz: Ejemplo <strong>de</strong> solución <strong>de</strong>l ejercicio “Django cms”<br />

14.6. Django cms put<br />

Enunciado:<br />

Realizar una sistema <strong>de</strong> gestión <strong>de</strong> contenidos muy simple con Django. Correspon<strong>de</strong>rá<br />

con <strong>la</strong> funcionalidad <strong>de</strong> “contentPutApp” (ejercicio 13.3), almacenando<br />

los contenidos en una base <strong>de</strong> datos. En otras pa<strong>la</strong>bras, será como “Django cms”<br />

(ejercicio 14.5), añadiendo <strong>la</strong> funcionalidad <strong>de</strong> que el usuario pueda poner contenidos<br />

mediante PUT, tal y como se explicó en el ejercicio <strong>de</strong> “contentPutApp”.<br />

Comentario:<br />

Para realizar este ejercicio, consultar el manual <strong>de</strong> Django, don<strong>de</strong> explica cómo<br />

se comporta el objeto HTTPRequest, que es siempre primer argumento en los<br />

métodos que estamos <strong>de</strong>finiendo en views.py. En particu<strong>la</strong>r, nos interesarán sus<br />

atributos “method” (que sirve para saber si nos está llegando un GET o un PUT)<br />

y “raw post data”, que nos da acceso a los datos (cuerpo) <strong>de</strong> <strong>la</strong> petición. A pesar<br />

<strong>de</strong> su nombre, este último atributo tiene esos datos tanto si <strong>la</strong> petición es un POST<br />

como si es un PUT.<br />

Material:<br />

cms put.tar.gz: Ejemplo <strong>de</strong> solución <strong>de</strong>l ejercicio “Django cms put”.<br />

14.7. Django cms users<br />

Enunciado:<br />

Realizar un proyecto Django con <strong>la</strong> misma funcionalidad que “Django cms put”,<br />

pero incluyendo un módulo <strong>de</strong> administración (lo que proporciona el “Admin site”<br />

<strong>de</strong> Django) y recursos para login y logout <strong>de</strong> usuarios (usando los módulos<br />

que nos proporciona Django por <strong>de</strong>fecto, según se indica en <strong>la</strong>s transparencias).<br />

A<strong>de</strong>más, cada página <strong>de</strong> contenidos (o cada mensaje indicando que una página<br />

no está disponible) <strong>de</strong>berá quedar anotada con <strong>la</strong> ca<strong>de</strong>na “Not logged in. Login”<br />

(siendo “Login” un en<strong>la</strong>ce al recurso <strong>de</strong> login) si no se está autenticado como usuario,<br />

o con <strong>la</strong> ca<strong>de</strong>na “Logged in as name. Logout” (siendo “name” el nombre <strong>de</strong><br />

usuario, y “Logout” un en<strong>la</strong>ce al recurso <strong>de</strong> logout) si se está autenticado como<br />

usuario.<br />

46


Comentario:<br />

Las aplicación Django “Admin site”, entre otras, utiliza el middleware CSRF<br />

(protección frente a “Cross Site Request Forgery”), que hay que tener en cuenta,<br />

especialmente en los formu<strong>la</strong>rios POST. En particu<strong>la</strong>r, es importante asegurarse<br />

<strong>de</strong> que se han referenciado los módulos <strong>de</strong> CSRF en settings.py:<br />

MIDDLEWARE_CLASSES = (<br />

...<br />

’django.middleware.csrf.CsrfViewMiddleware’,<br />

’django.middleware.csrf.CsrfResponseMiddleware’,<br />

...<br />

Más información sobre este tema:<br />

http://docs.djangoproject.com/en/<strong>de</strong>v/ref/contrib/csrf/<br />

14.8. Django cms users put<br />

Enunciado:<br />

Realizar un proyecto Django con <strong>la</strong> misma funcionalidad que “Django cms users”<br />

(ejercicio 14.7), tratando <strong>de</strong> que el proceso <strong>de</strong> login y logout sea lo más razonable<br />

posible e incluyendo <strong>la</strong> funcionalidad <strong>de</strong> que sólo los usuarios que estén autenticados<br />

pue<strong>de</strong>n cambiar el contenido <strong>de</strong> cualquier página, mientras que los que<br />

no lo están sólo pue<strong>de</strong>n ver <strong>la</strong>s páginas (funcionalidad simi<strong>la</strong>r a <strong>la</strong> <strong>de</strong> “Gestor <strong>de</strong><br />

contenidos con usuarios”).<br />

14.9. Django cms temp<strong>la</strong>tes<br />

Enunciado:<br />

Realizar un proyecto Django con <strong>la</strong> misma funcionalidad que “Django cms users put”<br />

(ejercicio 14.8), pero atendiendo a una nueva familia <strong>de</strong> recursos: “/annotated/”.<br />

Cualquier recurso que comience con “/annotated/” se servirá usando una p<strong>la</strong>ntil<strong>la</strong>,<br />

y por lo <strong>de</strong>más, con <strong>la</strong> misma funcionalidad que teníamos en “Django cms users put”<br />

al recibir un GET para el nombre <strong>de</strong> recurso.<br />

14.10. Django cms post<br />

Enunciado: Realizar un proyecto Django con <strong>la</strong> misma funcionalidad que<br />

“Django cms temp<strong>la</strong>tes” (ejercicio 14.9, pero atendiendo a una nueva familiar <strong>de</strong><br />

recursos: “/edit/”. Cuando se acceda con un GET a un recurso que comience por<br />

“/edit”, <strong>la</strong> aplicación web <strong>de</strong>volverá un formu<strong>la</strong>rio que permita editarlo (si se <strong>de</strong>tecta<br />

un usuario autenticado, y si el nombre <strong>de</strong> recurso existe como página en<br />

47


<strong>la</strong> base <strong>de</strong> datos <strong>de</strong> <strong>la</strong> aplicación). Ese formu<strong>la</strong>rio tendrá un único campo que se<br />

precargará con el contenido <strong>de</strong> esa página. Si se acce<strong>de</strong> con POST a un recurso<br />

que comience por “/edit/”, se utilizará el valor que venga en él para actualizar <strong>la</strong><br />

página correspondiente, si el usuario está autenticado y <strong>la</strong> página existe. A<strong>de</strong>más,<br />

volverá a <strong>de</strong>volver el formu<strong>la</strong>rio igual que con el GET, para que el usuario pueda<br />

continuar editando si así lo <strong>de</strong>sea.<br />

14.11. Django feed expan<strong>de</strong>r<br />

Utilizando Django y, en <strong>la</strong> medida que te parezca conveniente, feedparser.py<br />

y BeautifulSoup.py, realiza un servicio que expanda el contenido <strong>de</strong>l canal <strong>de</strong><br />

un usuario <strong>de</strong> Twitter. El servicio aten<strong>de</strong>rá peticiones a recursos <strong>de</strong> <strong>la</strong> forma<br />

/feed/user (siendo “user” el i<strong>de</strong>ntificador <strong>de</strong> un usuario <strong>de</strong> Twitter), <strong>de</strong>volviendo<br />

una página HTML con:<br />

Los cinco últimos twits <strong>de</strong>l usuario.<br />

Para cada uno <strong>de</strong> ellos, <strong>la</strong> lista <strong>de</strong> urls que incluye (consi<strong>de</strong>rando como tales,<br />

por ejemplo, <strong>la</strong>s subca<strong>de</strong>nas <strong>de</strong> caracteres <strong>de</strong>limitads por espacios y que<br />

comiencen por “http://”.<br />

Para cada una <strong>de</strong> estas urls:<br />

• El texto <strong>de</strong>l primer elemento < p > <strong>de</strong> <strong>la</strong> página correspondiente, si<br />

existe.<br />

• Las imágenes (i<strong>de</strong>ntificadas como elementos < img > que contenga <strong>la</strong><br />

página correspondiente, si existen.<br />

Los canales <strong>de</strong> usuarios <strong>de</strong> Twitter están disponibles en formato RSS en urls como<br />

https://twitter.com/statuses/user_timeline/user.rss, para el usuario<br />

“user”.<br />

Pue<strong>de</strong>n usarse tambien <strong>la</strong>s bibliotecas urllib2 para <strong>la</strong> <strong>de</strong>scarga <strong>de</strong> páginas mediante<br />

HTTP, y urlparse para manipu<strong>la</strong>r urls (ambos son módulos estándar <strong>de</strong><br />

Python).<br />

Referencias:<br />

Documentación sobre feedparser.py (via WayBack Machine):<br />

http://web.archive.org/web/20110625112257/http://feedparser.org/<br />

docs/<br />

Presentación sobre feedparser.py:<br />

http://www.sli<strong>de</strong>share.net/LindseySmith1/feedparser<br />

48


Documentación sobre BeautifulSoup.py:<br />

http://www.crummy.com/software/BeautifulSoup/documentation.html<br />

14.12. Django feed expan<strong>de</strong>r db<br />

Realiza un servicio que proporcione <strong>la</strong> misma funcionalidad que “Django feed expan<strong>de</strong>r”<br />

(ejercicio 14.11), pero almacenando los datos en tab<strong>la</strong>s en una base <strong>de</strong> datos. Más<br />

en <strong>de</strong>talle:<br />

El recurso /feed/user seguirá haciendo lo mismo, para el usuario “user” <strong>de</strong><br />

Twitter. Pero a<strong>de</strong>más <strong>de</strong> mostrar <strong>la</strong> página web resultante, almacenará entab<strong>la</strong>s<br />

en <strong>la</strong> base <strong>de</strong> datos:<br />

• Los cinco últimos twits <strong>de</strong>l usuario, y el usuario al que se refieren<br />

• La lista <strong>de</strong> urls <strong>de</strong> cada twit<br />

• El texto <strong>de</strong>l primer elemento < p > <strong>de</strong> <strong>la</strong> página referenciada por cada<br />

url.<br />

• Las imágenes <strong>de</strong> dicha página.<br />

En todos estos casos, <strong>la</strong> información se añadirá a <strong>la</strong> que haya ya previamente<br />

en <strong>la</strong>s tab<strong>la</strong>s correspondientes.<br />

El recurso /db/user mostrará <strong>la</strong> misma página que se muestra para /feed/user,<br />

pero incluyendo toda <strong>la</strong> información disponible en <strong>la</strong> base <strong>de</strong> datos para ese<br />

usuario (esto es, no limitado a los cinco últimos twits, si hubiera más <strong>de</strong>n <strong>la</strong><br />

base <strong>de</strong> datos). Para mostrar <strong>la</strong> página mencionada, no se acce<strong>de</strong>rá a ningún<br />

recurso externo: sólo a <strong>la</strong> información en <strong>la</strong> base <strong>de</strong> datos.<br />

Comentarios:<br />

Se pue<strong>de</strong>n realizar varios diseños <strong>de</strong> tab<strong>la</strong>s en <strong>la</strong> base <strong>de</strong> datos para este ejercicio.<br />

Entre ellos, se sugieren los basados en el siguiente esquema:<br />

Tab<strong>la</strong> <strong>de</strong> twits, con dos campos: usuarios y twits, ambos ca<strong>de</strong>nas <strong>de</strong> texto<br />

(a<strong>de</strong>más, Django mantendrá un campo id para cada twit).<br />

Tab<strong>la</strong> <strong>de</strong> urls, con dos campos: id <strong>de</strong> twit y url, el primero un id, el segundo<br />

ca<strong>de</strong>na <strong>de</strong> texto (a<strong>de</strong>más, Django mantendrá un campo id para cada url).<br />

Tab<strong>la</strong> <strong>de</strong> textos, con dos campos: id <strong>de</strong> url y texto (contenido <strong>de</strong> < p >,<br />

ca<strong>de</strong>na <strong>de</strong> texto).<br />

49


Tab<strong>la</strong> <strong>de</strong> imágenes, con dos campos: id <strong>de</strong> url e imagen (ca<strong>de</strong>na <strong>de</strong> texto con<br />

<strong>la</strong> url <strong>de</strong> <strong>la</strong> imagen).<br />

Des<strong>de</strong> luego, este esquema se pue<strong>de</strong> simplificar y complicar, pero quizás sea un<br />

buen punto medio para empezar a trabajar.<br />

15. Ejercicios P6: Aplicaciones web con base <strong>de</strong><br />

datos<br />

Construcción <strong>de</strong> aplicaciones web con almacenamiento estable en base <strong>de</strong> datos.<br />

15.1. Introducción a SQLite3 con Python<br />

Enunciado:<br />

Vamos a empezar a usar bases <strong>de</strong> datos re<strong>la</strong>cionales con nuestras aplicaciones<br />

web. En particu<strong>la</strong>r, vamos a usar el módulo Python sqlite3, que proporciona en<strong>la</strong>ce<br />

con el gestor <strong>de</strong> bases <strong>de</strong> datos SQLite3, que utiliza una interfaz SQL. Estudiar testdb.py,<br />

para enten<strong>de</strong>r cómo se hacen operaciones básicas sobre una base <strong>de</strong> datos<br />

con Python. Modificar ese programa para que añada más registros, y comprobar<br />

con sqlitebrowser <strong>la</strong> base <strong>de</strong> datos creada.<br />

Material:<br />

test-db.py. <strong>Programa</strong> que crea una base <strong>de</strong> datos simple SQLite3, y luego <strong>la</strong><br />

muestra en pantal<strong>la</strong>.<br />

15.2. Gestor <strong>de</strong> contenidos con base <strong>de</strong> datos<br />

Enunciado:<br />

Escribe y prueba <strong>la</strong> c<strong>la</strong>se contentDBApp, que será una versión <strong>de</strong> contentApp<br />

(ejercicio 13.1), pero utilizando una base <strong>de</strong> datos SQLite3 para almacenar sus<br />

objetos persistentes.<br />

15.3. Gestor <strong>de</strong> contenidos con usuarios, con control estricto<br />

<strong>de</strong> actualización y base <strong>de</strong> datos<br />

Enunciado:<br />

Escribe y prueba <strong>la</strong> c<strong>la</strong>se contentDBAppUsersStrict, que será igual que “Gestor<br />

<strong>de</strong> contenidos con usuarios, con control estricto <strong>de</strong> actualización” (contentAppUsersStrict,<br />

ejercicio 13.8), pero usando base <strong>de</strong> datos como almacenamiento permanente.<br />

50


16. Prácticas <strong>de</strong> entrega voluntaria y final (SA-<br />

RO, curso 2011-2012<br />

Estas prácticas se pue<strong>de</strong> entregar para su evaluación como parte <strong>de</strong> <strong>la</strong> nota <strong>de</strong><br />

prácticas (ver apartado sobre evaluación <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>).<br />

16.1. Práctica 1 (entrega voluntaria)<br />

Fecha <strong>de</strong> entrega: 7 <strong>de</strong> febrero <strong>de</strong> 2012 a <strong>la</strong>s 23:55.<br />

La programación orientada a objetos en un paradigma <strong>de</strong> programación muy<br />

utilizado en <strong>la</strong> actualidad y que conviene conocer para <strong>la</strong> realización <strong>de</strong> <strong>la</strong>s prácticas<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>. En esta práctica se preten<strong>de</strong>n ver los conceptos más importantes<br />

<strong>de</strong> este paradigma, implementando funcionalidad en Python.<br />

Para <strong>la</strong> evaluación <strong>de</strong> esta entrega se valorará que <strong>la</strong> entrega sea correcta, el<br />

correcto funcionamiento, y también el seguimiento <strong>de</strong> <strong>la</strong> guía <strong>de</strong> estilo <strong>de</strong> Python.<br />

Tiempo estimado <strong>de</strong> realización: 6 horas.<br />

16.1.1. Objetivos <strong>de</strong> <strong>la</strong> práctica<br />

Conocer y practicar <strong>la</strong> programación orientada a objetos.<br />

Ac<strong>la</strong>rar conceptos como encapsu<strong>la</strong>miento, herencia, instanciación, polimorfismo...<br />

Uso <strong>de</strong> varios módulos Python, importando funcionalidad creada en otros<br />

módulos<br />

16.1.2. Conocimientos previos necesarios<br />

Nociones <strong>de</strong> Python (<strong>la</strong>s <strong>de</strong> <strong>la</strong> primera práctica) y <strong>de</strong> orientación a objetos.<br />

16.1.3. Ejercicios a realizar<br />

1. Dentro <strong>de</strong> tu home en el <strong>la</strong>boratorio, crea un directorio saro y <strong>de</strong>ntro <strong>de</strong> éste,<br />

otro p1. Las instrucciones shell para hacerlo son <strong>la</strong>s siguientes:<br />

$ mkdir -p ~/saro/p1<br />

$ cd ~/saro/p1<br />

Trabaja a partir <strong>de</strong> ahora en este directorio.<br />

51


2. Crea en el archivo persona.py una c<strong>la</strong>se en Python que implemente una<br />

persona. Esta c<strong>la</strong>se, <strong>de</strong> nombre Persona, <strong>de</strong>berá tener:<br />

Una ca<strong>de</strong>na <strong>de</strong>scriptiva tipo “docstring”.<br />

Atributos para:<br />

• nombre: el nombre completo.<br />

• correoe: La dirección <strong>de</strong> correo-e.<br />

Métodos (recuerda que los métodos requieren una ca<strong>de</strong>na <strong>de</strong>scriptiva<br />

tipo docstring):<br />

• Constructor (que permite introducir los valores <strong>de</strong> los atributos, si<br />

así se <strong>de</strong>sea).<br />

• set nombre y set correo: introduce nuevo valor para atributo.<br />

• get nombre y get correo: lee valor ya introducido.<br />

• print persona: imprime por pantal<strong>la</strong> todos los atributos <strong>de</strong>l contacto<br />

(nombre y correo-e).<br />

3. Crea un programa principal en persona.py que haga lo siguiente:<br />

Se instancie un objeto <strong>de</strong> <strong>la</strong> c<strong>la</strong>se Persona: “Angel” y “angel@saro.com”<br />

Se compruebe con print persona()<br />

Se modifique los valores <strong>de</strong>l objeto haciendo uso <strong>de</strong> los métodos set *<br />

(modificándolos por “Iciar” y “iciar@saro.com”)<br />

Se compruebe que el valor <strong>de</strong> los atributos haciendo un print <strong>de</strong> los<br />

métodos get * y <strong>de</strong> print persona()<br />

Se acceda directamente a los atributos nombre y correo-e sin hacer uso<br />

<strong>de</strong> los métodos. Nota que es posible, aunque hay gente que dice que esto<br />

no es <strong>de</strong>seable (esto quiere <strong>de</strong>cir que Python no utiliza encapsu<strong>la</strong>miento).<br />

4. Crea una nueva c<strong>la</strong>se, que here<strong>de</strong> <strong>de</strong> Persona, l<strong>la</strong>mada Contacto y guárda<strong>la</strong> en<br />

contacto.py. Esta c<strong>la</strong>se quiere mo<strong>de</strong><strong>la</strong>r una persona, pero con particu<strong>la</strong>rida<strong>de</strong>s<br />

específicas, en particu<strong>la</strong>r que pueda tener contactos (en nuestro ejercicio, un<br />

contacto es una persona con contactos). Crearemos por tanto una c<strong>la</strong>se hija<br />

hereda <strong>de</strong> <strong>la</strong> c<strong>la</strong>se padre Persona. Para ello, habrá que crear una c<strong>la</strong>se con los<br />

siguientes atributos y métodos nuevos o re<strong>de</strong>finidos (recuér<strong>de</strong>se que aquellos<br />

atributos/métodos que no estén re<strong>de</strong>finidos se tomarán <strong>de</strong> <strong>la</strong> c<strong>la</strong>se padre):<br />

Atributos (nuevos o re<strong>de</strong>finidos):<br />

52


• contactos: lista <strong>de</strong> contactos (lista <strong>de</strong> objetos <strong>de</strong>l tipo Persona)<br />

Métodos (nuevos o re<strong>de</strong>finidos):<br />

• Constructor: a<strong>de</strong>más <strong>de</strong> indicar nombre y correo-e, iniciará el atributo<br />

contactos a vacío.<br />

• add contacto: permite añadir un objeto Persona como contacto.<br />

• get contactos: <strong>de</strong>volverá una lista con los objetos que son contacto.<br />

• get num contactos: Devuelve el número <strong>de</strong> contactos.<br />

• print contacto: Imprime los valores (nombre, correo-e y los nombres<br />

<strong>de</strong> los contactos) <strong>de</strong>l objeto.<br />

5. Crea un programa principal en contacto.py que haga lo siguiente:<br />

Se instancie un objeto <strong>de</strong> <strong>la</strong> c<strong>la</strong>se Contacto: “Sebas” y “sebas@saro.com”<br />

Se compruebe con print persona() y con print contacto()<br />

Se instancie un objeto <strong>de</strong> <strong>la</strong> c<strong>la</strong>se Persona: “Brilly” y “brilly@saro.com”<br />

Se añada a Brilly como contacto <strong>de</strong> Sebas (ojo, eso no quiere <strong>de</strong>cir que<br />

Sebas sea contacto <strong>de</strong> Brilly).<br />

Se compruebe con print persona(), print contacto() y get num contactos()<br />

(en Brilly y Sebas, si se pue<strong>de</strong>).<br />

6. Crea un programa principal (p1.py) que haga lo siguiente:<br />

Instancie 2 objetos <strong>de</strong>l tipo Persona (l<strong>la</strong>mados ana y manuel)<br />

Instancie 2 objetos <strong>de</strong>l tipo Contacto (l<strong>la</strong>mados bea y fernando)<br />

Que ana se añada a <strong>la</strong> lista <strong>de</strong> contactos <strong>de</strong> bea y fernando.<br />

Que bea se añada a <strong>la</strong> lista <strong>de</strong> contactos <strong>de</strong> fernando.<br />

¿Podría añadir a bea a <strong>la</strong> lista <strong>de</strong> contactos <strong>de</strong> manuel ¿Por qué no<br />

L<strong>la</strong>ma al método print persona() <strong>de</strong> los contactos <strong>de</strong> fernando. La lista<br />

<strong>de</strong> contactos <strong>de</strong> fernando <strong>la</strong> pue<strong>de</strong>s conseguir utilizando get contactos().<br />

Nota que al l<strong>la</strong>mar a print persona hacemos uso <strong>de</strong> polimorfismo, porque<br />

estaremos l<strong>la</strong>mando al método print persona que <strong>de</strong>pendiendo <strong>de</strong>l<br />

objeto que le pasemos será el print persona <strong>de</strong> <strong>la</strong> c<strong>la</strong>se Persona o el <strong>de</strong><br />

<strong>la</strong> c<strong>la</strong>se Contacto.<br />

16.1.4. Entrega <strong>de</strong> <strong>la</strong> práctica<br />

Para <strong>la</strong> entrega, habrá que <strong>de</strong>jar en <strong>la</strong> cuenta <strong>de</strong>l <strong>la</strong>boratorio <strong>de</strong>l alumno que<br />

<strong>la</strong> está realizando un directorio /saro/p1 con:<br />

53


3 módulos Python:<br />

• persona.py<br />

• contacto.py<br />

• p1.py<br />

que contienen a su vez 2 c<strong>la</strong>ses:<br />

• Persona (en pesona.py)<br />

• Contacto que heredará <strong>de</strong> Persona (en contacto.py)<br />

16.2. Práctica 2 (entrega voluntaria)<br />

Fecha recomendada <strong>de</strong> entrega: Antes <strong>de</strong>l 21 <strong>de</strong> marzo.<br />

Esta práctica tendrá como objetivo <strong>la</strong> creación <strong>de</strong> una aplicación web para<br />

acceso a los artículos <strong>de</strong> Wikipedia con almacenamiento en cache.<br />

La aplicación servirá dos tipos <strong>de</strong> recursos:<br />

“/<strong>de</strong>corated/article”: servirá <strong>la</strong> página correspondiente al artículo “article”<br />

<strong>de</strong> <strong>la</strong> Wikipedia en inglés, <strong>de</strong>corado con <strong>la</strong>s cajas auxiliares.<br />

“/raw/article”: servirá <strong>la</strong> página correspondiente al artículo “article” <strong>de</strong> <strong>la</strong><br />

Wikipedia en inglés, sin <strong>de</strong>corar con <strong>la</strong>s cajas auxiliares.<br />

La página “<strong>de</strong>corada” es accesible mediante URLs <strong>de</strong> <strong>la</strong> siguiente forma (para<br />

el artículo “pencil” <strong>de</strong> <strong>la</strong> Wikipedia en inglés):<br />

http://en.wikipedia.org/w/in<strong>de</strong>x.phptitle=pencil&action=view<br />

El contenido que sirven estas URLs está previsto para ser directamente mostrado,<br />

como página HTML completa, por un navegador.<br />

La página “no <strong>de</strong>corada” es accesible mediante URLs <strong>de</strong> <strong>la</strong> siguiente forma<br />

(para el artículo “pencil” <strong>de</strong> <strong>la</strong> Wikipedia en inglés):<br />

http://en.wikipedia.org/w/in<strong>de</strong>x.phptitle=pencil&action=ren<strong>de</strong>r<br />

El contenido que sirven estas URLs está previsto para ser directamente empotrable<br />

en una página HTML, <strong>de</strong>ntro <strong>de</strong>l elemento “body” (y por lo tanto <strong>la</strong><br />

aplicación web tendrá que aportar el HTML necesario para acabar teniendo una<br />

página HTML correcta).<br />

54


Cualquiera <strong>de</strong> los dos tipos <strong>de</strong> recursos se comportará <strong>de</strong> <strong>la</strong> misma forma. Si<br />

es invocado mediante GET, usará para respon<strong>de</strong>r el artículo que tenga en cache.<br />

Si no lo tiene, lo bajará previamente accediendo a <strong>la</strong> URL a<strong>de</strong>cuada, que se<br />

indicó anteriormente, lo almacenará en <strong>la</strong> cache, y lo usará para respon<strong>de</strong>r.<br />

La respuesta, en cada caso, será una página HTML que contenga en <strong>la</strong> parte<br />

superior <strong>la</strong> siguiente información:<br />

Nombre <strong>de</strong>l artículo, junto con <strong>la</strong> indicación “(<strong>de</strong>corated)” o “(non <strong>de</strong>corated)”,<br />

según corresponda. Por ejemplo, “Pencil (<strong>de</strong>corated)”.<br />

En<strong>la</strong>ces a <strong>la</strong>s páginas con el artículo en <strong>la</strong> Wikipedia (versiones <strong>de</strong>corada y<br />

no <strong>de</strong>corada)<br />

En<strong>la</strong>ce a <strong>la</strong> historia <strong>de</strong> modificaciones <strong>de</strong>l artículo en <strong>la</strong> Wikipedia<br />

En<strong>la</strong>ce al último artículos <strong>de</strong> <strong>la</strong> Wikipedia que ha servido <strong>la</strong> aplicación (al<br />

navegador que le hizo <strong>la</strong> petición, o a cualquier otro).<br />

Línea <strong>de</strong> separación (elemento “hr”).<br />

Y a continuación el texto correspondiente <strong>de</strong>l artículo <strong>de</strong> <strong>la</strong> Wikipedia (<strong>de</strong>corado<br />

o no <strong>de</strong>corado, según sea el nombre <strong>de</strong>l recurso invocado).<br />

En caso <strong>de</strong> que se pida un artículo que no exista en <strong>la</strong> Wikipedia, se <strong>de</strong>volverá el<br />

código <strong>de</strong> error correspondiente, y se marcará en <strong>la</strong> cache, <strong>de</strong> alguna forma, que ese<br />

artículo no existe, para no tener que buscarlo en caso <strong>de</strong> que vuelva a ser pedido.<br />

En general, pue<strong>de</strong> usarse algún texto que aparezca en <strong>la</strong> página que <strong>de</strong>vuelve<br />

Wikipedia cuando sirve <strong>la</strong> página <strong>de</strong> un artículo que no existe, como por ejemplo:<br />

<br />

Materiales <strong>de</strong> apoyo:<br />

Parámetros <strong>de</strong> in<strong>de</strong>x.php en Wikipedia (MediaWiki): http://www.mediawiki.<br />

org/wiki/Manual:Parameters_to_in<strong>de</strong>x.php#View_and_ren<strong>de</strong>r<br />

Comentario:<br />

En algunas circunstancias, el servidor <strong>de</strong> Wikipedia pue<strong>de</strong> <strong>de</strong>volver un código<br />

<strong>de</strong> redirección (por ejmeplo, un “301 Moved permanently”). Téngase en cuenta<br />

que <strong>la</strong> aplicación ha <strong>de</strong> reconocer esta situación, y repetir el GET en <strong>la</strong> url a <strong>la</strong><br />

que se redirige.<br />

55


16.3. Práctica 3 (entrega voluntaria)<br />

Fecha recomendada <strong>de</strong> entrega: 11 <strong>de</strong> abril.<br />

Realiza lo especificado en <strong>la</strong> práctica 2 (ejercicio 16.2), pero usando el entorno<br />

<strong>de</strong> <strong>de</strong>sarrollo Django. En particu<strong>la</strong>r, utiliza p<strong>la</strong>ntil<strong>la</strong>s (temp<strong>la</strong>tes) para <strong>la</strong> generación<br />

<strong>de</strong> <strong>la</strong>s páginas HTML, tab<strong>la</strong>s en base <strong>de</strong> datos para almacenar <strong>la</strong>s páginas <strong>de</strong><br />

Wikipedia <strong>de</strong>scargada, y aña<strong>de</strong> <strong>la</strong> siguiente funcionalidad:<br />

Utilizando el módulo correspondinete <strong>de</strong> Django, aña<strong>de</strong> usuarios, que se autenticarán<br />

en el recurso “/login”. Las cuentas <strong>de</strong> usuario estarán dadas <strong>de</strong><br />

alta por el administrador (vía módulo Admin <strong>de</strong> Django). Si una página es<br />

bajada por un usuario autenticado se incluirá en <strong>la</strong> parte superior el mensaje<br />

“Usuario: user (logout)”, siendo “user” el i<strong>de</strong>ntificador <strong>de</strong> usuario correspondiente,<br />

y “logout” un en<strong>la</strong>ce al recurso que pue<strong>de</strong> utilizar el usuario para salir<br />

<strong>de</strong> su cuenta. Si <strong>la</strong> página es bajada sin haberse autenticado previamente, en<br />

lugar <strong>de</strong> ese mensaje se incluirá “Usuario anónimo (login)”, siendo “login”<br />

un en<strong>la</strong>ce al recurso “/login”.<br />

La aplicación aten<strong>de</strong>rá el recurso “/”, en el que ofrecerá (si se invoca con<br />

“GET”) una lista <strong>de</strong> los artículos <strong>de</strong> Wikipedia disponibles en <strong>la</strong> base <strong>de</strong><br />

datos, junto al en<strong>la</strong>ce correspondiente (bajo “/<strong>de</strong>corated” o bajo “/raw”)<br />

para <strong>de</strong>scargar<strong>la</strong>, y el mensaje “<strong>de</strong>corated” o “raw”, según el tipo <strong>de</strong> artículo<br />

<strong>de</strong>scargado.<br />

17. Práctica final (2012, mayo)<br />

[Este enunciado es aún tentativo, incompleto, y está sujeto a cambios]<br />

La práctica final <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> consiste en <strong>la</strong> creación <strong>de</strong> un sitio web <strong>de</strong><br />

microresúmenes, ResumeMe. A continuación se <strong>de</strong>scribe el funcionamiento y arquitectura<br />

general <strong>de</strong> <strong>la</strong> aplicación, <strong>la</strong> funcionalidad mínima que <strong>de</strong>be proporcionar,<br />

y otra funcionalidad optativa que podrá tener.<br />

17.1. Arquitectura y funcionamiento general<br />

Arquitectura general:<br />

La práctica consistirá en una aplicación web que servirá los datos a los usuarios.<br />

La aplicación web se construirá como un proyecto Django, que incluirá una<br />

o varias aplicaciones Django que implementen <strong>la</strong> funcionalidad requerida.<br />

56


Para el almacenamiento <strong>de</strong> datos persistente se usará SQLite3, con tab<strong>la</strong>s<br />

<strong>de</strong>finidas según mo<strong>de</strong>los en Django.<br />

Se usará <strong>la</strong> aplicación Django “Admin site” para mantener los usuarios con<br />

cuenta en el sistema, y para <strong>la</strong> gestión general <strong>de</strong> <strong>la</strong>s bases <strong>de</strong> datos necesarias.<br />

Se utilizarán p<strong>la</strong>ntil<strong>la</strong>s Django (a ser posible, una jerarquía <strong>de</strong> p<strong>la</strong>ntil<strong>la</strong>s, para<br />

que toda <strong>la</strong> aplicación tenga un aspecto simi<strong>la</strong>r) para <strong>de</strong>finir <strong>la</strong>s páginas que<br />

se servirán a los navegadores <strong>de</strong> los usuarios. Estas p<strong>la</strong>ntil<strong>la</strong>s incluirán en<br />

todas <strong>la</strong>s páginas al menos:<br />

• Un banner (imagen) <strong>de</strong>l sitio, en <strong>la</strong> parte superior.<br />

• Un menú <strong>de</strong> opciones también en <strong>la</strong> parte superior.<br />

• Un pie <strong>de</strong> página con una nota <strong>de</strong> copyright.<br />

Se utilizarán hojas <strong>de</strong> estilo CSS para <strong>de</strong>terminar <strong>la</strong> apariencia <strong>de</strong> <strong>la</strong> aplicación.<br />

Funcionamiento general:<br />

El sitio ResumeMe ofrece como servicio <strong>la</strong> construcción <strong>de</strong> listados <strong>de</strong> microresúmenes,<br />

obtenidos a partir <strong>de</strong> canales RSS <strong>de</strong> ciertos sitios terceros.<br />

Para construir un microresumen, primero se extraerán los títulos y urls <strong>de</strong><br />

<strong>la</strong>s últimas noticias <strong>de</strong> los canales correspondientes. Con esta información se<br />

ofrecerá al usuario <strong>la</strong> opción <strong>de</strong> incluir cada uno <strong>de</strong> ellos en el microresumen,<br />

mediante un botón asociado al título.<br />

Cada usuario autenticado dispondrá <strong>de</strong> una url en <strong>la</strong> que podrá configurar<br />

su microresumen indicando en qué información <strong>de</strong> sitios terceros están<br />

interesados (eligiendo los canales RSS correspondientes).<br />

Cada usuario dispondrá <strong>de</strong> una url en <strong>la</strong> que podrá ver los últimos titu<strong>la</strong>res<br />

<strong>de</strong> los canales RSS configurados para su microresumen, pudiendo marcar<br />

cualquiera <strong>de</strong> ellos para ser incluido en su microresumen.<br />

Para cada usuario habrá una url, que podrá consultar cualquier visitante sin<br />

autentificar o usuario autentificado <strong>de</strong>l sitio, en <strong>la</strong> que verá los titu<strong>la</strong>res <strong>de</strong><br />

su microresumen.<br />

Cada titu<strong>la</strong>r <strong>de</strong> un microresumen será en realidad un en<strong>la</strong>ce que apunte al<br />

sitio que indica el elemento RSS <strong>de</strong>l que se extrajo. Junto a él, irá también<br />

un en<strong>la</strong>ce a ese canal RSS <strong>de</strong>l que se extrajo.<br />

57


Cuando esté visitando ResumeMe un visitante sin autenticar, le aparecerá una<br />

caja para autenticarse. Si es un usuario autenticado, le aparecerá un mecanismo<br />

para salir <strong>de</strong> <strong>la</strong> cuenta (“<strong>de</strong>sautenticarse”).<br />

17.2. Esquema básico <strong>de</strong> recursos servidos<br />

Recursos a servir como páginas HTML completas (pensadas para ser vistas en<br />

el navegador):<br />

/: Página principal <strong>de</strong> ResumeMe con texto <strong>de</strong> bienvenida, en<strong>la</strong>ce a cada uno<br />

<strong>de</strong> lo microresúmenes (uno por usuario), indicando el número <strong>de</strong> veces que<br />

ha sido visto, y 10 titu<strong>la</strong>res elegidos aleatoriamente entre los <strong>de</strong> todos los<br />

microresúmenes.<br />

/usuario: Microresumen para el usuario “usuario”. No podrá haber usuarios<br />

con los nombres “conf”, “elige” o “micss”.<br />

/conf: Página <strong>de</strong> configuración <strong>de</strong> los canales para alimentar el microresumen<br />

<strong>de</strong>l usuario que acce<strong>de</strong> a el<strong>la</strong>.<br />

/elige: Página para elegir titu<strong>la</strong>res a partir <strong>de</strong> los últimos titu<strong>la</strong>res <strong>de</strong> los<br />

canales RSS configurados por el usuario que acce<strong>de</strong> a el<strong>la</strong>.<br />

/micss: Mostrará un formu<strong>la</strong>rio para cambiar el CSS que se usará para mostrar<br />

cualquier página que vea el usuario que <strong>la</strong> visita.<br />

A<strong>de</strong>más <strong>de</strong> estos recursos, se aten<strong>de</strong>rá a cualquier otro que sea necesario para<br />

proporcionar <strong>la</strong> funcionalidad indicada.<br />

17.3. Funcionalidad mínima<br />

Esta es <strong>la</strong> funcionalidad mínima que habrá <strong>de</strong> proporcionar <strong>la</strong> aplicación:<br />

Para cada página /usuario se mostrará a cualquier visitante no autenticado:<br />

• El nombre <strong>de</strong>l usuario al que correspon<strong>de</strong> el microresumen<br />

• Los titu<strong>la</strong>res elegidos para el microresumen, incluyendo:<br />

◦ El título (titu<strong>la</strong>r), como en<strong>la</strong>ce que apunte a <strong>la</strong> url que venía en el<br />

elemento <strong>de</strong>l canal RSS <strong>de</strong>l que se extrajo.<br />

◦ Junto a él, el nombre <strong>de</strong> dicho canal RSS, como en<strong>la</strong>ce a <strong>la</strong> url <strong>de</strong>l<br />

canal.<br />

58


Para cada página /usuario, si <strong>la</strong> visita el usuario autenticado “usuario”, se<br />

mostrará junto a cada titu<strong>la</strong>r un botón para elmiminarlo <strong>de</strong>l microresumen.<br />

Para cada página /usuario, si lo visita un usuario autenticado que no sea<br />

“usuario”, se mostrará junto a cada titu<strong>la</strong>r un botón para añadirlo a su<br />

propio microresumen.<br />

Para cada página /conf, si <strong>la</strong> visita un usuario autenticado, se mostrará una<br />

lista <strong>de</strong> los canales para elegir titu<strong>la</strong>res para el microresumen correspondiente,<br />

más una caja para po<strong>de</strong>r indicar <strong>la</strong> url <strong>de</strong> un canal RSS más. Si <strong>la</strong> visita un<br />

visitante no autenticado, se mostrará un error.<br />

Para cada página /elige, si <strong>la</strong> visita un usuario autenticado, se mostrará una<br />

lista con los últimos titu<strong>la</strong>tes <strong>de</strong> cada canal configurado para el microresumen<br />

<strong>de</strong> ese usuario. Si <strong>la</strong> visita un visitante no autenticado, se mostrará un error.<br />

Para cada página /micss, si <strong>la</strong> visita un usuario autenticado, se mostratá un<br />

formu<strong>la</strong>rio con <strong>la</strong> última versión <strong>de</strong>l CSS <strong>de</strong> ese usuario, o el CSS por <strong>de</strong>fecto<br />

si no lo ha modificado nunca. Ese CSS habrá <strong>de</strong> ser capaz, como mínimo,<br />

<strong>de</strong> cambiar el color <strong>de</strong> fondo y el <strong>de</strong> <strong>la</strong>s letras <strong>de</strong> todo el sitio, cuando lo<br />

esté visitando ese usuario autenticado.<br />

17.4. Funcionalidad optativa<br />

De forma optativa, se podrá incluir cualquier funcionalidad relevante en el<br />

contexto <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>. Se valorarán especialmente <strong>la</strong>s funcionalida<strong>de</strong>s que impliquen<br />

el uso <strong>de</strong> técnicas nuevas, o <strong>de</strong> aspectos <strong>de</strong> Django no utilizados en los<br />

ejercicios previos, y que tengan sentido en el contexto <strong>de</strong> esta práctica y <strong>de</strong> <strong>la</strong><br />

<strong>asignatura</strong>.<br />

Sólo a modo <strong>de</strong> sugerencia, se incluyen algunas posibles funcionalida<strong>de</strong>s optativas:<br />

Inclusión <strong>de</strong> imágenes en los microresúmenes, utilizando <strong>la</strong>s que aparecen en<br />

los canales RSS.<br />

Puntuación <strong>de</strong> microresumenes. Cada usuario registrado pue<strong>de</strong> puntuar cualquier<br />

microresumen <strong>de</strong>l sitio, por ejemplo entre 1 y 5. Estas puntuaciones se<br />

podrán ver luego junto al microresumen en cuestión.<br />

Comentarios a titu<strong>la</strong>res. Cada usuario registrado pue<strong>de</strong> comentar cualquier<br />

titu<strong>la</strong>r. Estos comentarios se podrán ver luego junto al titu<strong>la</strong>r en cuestión.<br />

Soporte para avatares. Cada usuario podrá subir una imagen que aparecerá<br />

en su microresumen.<br />

59


17.5. Entrega <strong>de</strong> <strong>la</strong> práctica<br />

Fecha límite <strong>de</strong> entrega <strong>de</strong> <strong>la</strong> práctica: 11 <strong>de</strong> mayo <strong>de</strong> 2012.<br />

La práctica se entregará subiéndo<strong>la</strong> al recurso habilitado a tal fin en el sitio<br />

Moodle <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>. Los alumnos que no entreguen <strong>la</strong>s práctica <strong>de</strong> esta forma<br />

serán consi<strong>de</strong>rados como no presentados en lo que a <strong>la</strong> entrega <strong>de</strong> prácticas se<br />

refiere. Los que <strong>la</strong> entreguen podrán ser l<strong>la</strong>mados a realizar también una entrega<br />

presencial, que tendrá lugar durante <strong>la</strong> primera semana lectiva <strong>de</strong> enero (<strong>la</strong> fecha y<br />

hora exacta se les comuicará oportunamente). Esta entrega presencial podrá incluir<br />

una conversación con el profesor sobre cualquier aspecto <strong>de</strong> <strong>la</strong> realización <strong>de</strong> <strong>la</strong><br />

práctica.<br />

Para entregar <strong>la</strong> práctica en el Moodle, cada alumno subirá al recurso habilitado<br />

a tal fin un fichero tar.gz con todo el código fuente <strong>de</strong> <strong>la</strong> práctica. El fichero se<br />

habrá <strong>de</strong> l<strong>la</strong>mar practica-alumno.tar.gz, siendo “alumno” el nombre <strong>de</strong> <strong>la</strong> cuenta<br />

<strong>de</strong>l alumno en el <strong>la</strong>boratorio.<br />

El fichero que se entregue <strong>de</strong>berá constar <strong>de</strong> un proyecto Django completo y<br />

listo para funcionar en el entorno <strong>de</strong>l <strong>la</strong>boratorio, incluyendo <strong>la</strong> base <strong>de</strong> datos con<br />

datos suficientes como para po<strong>de</strong>r probarlo. Estos datos incluirán al menos tres<br />

usuarios con sus microresumens correspondientes. Al menos una <strong>de</strong> estas microresumens<br />

incluirá al menos cinco titu<strong>la</strong>res. Se incluirá también un fichero README<br />

con los siguientes datos:<br />

Nombre <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Nombre completo <strong>de</strong>l alumno.<br />

Nombre <strong>de</strong> su cuenta en el <strong>la</strong>boratorio.<br />

Nombres y contraseñas <strong>de</strong> los usuarios creados para <strong>la</strong> práctica.<br />

Resumen <strong>de</strong> <strong>la</strong>s peculiarida<strong>de</strong>s que se quieran mencionar sobre lo implementado<br />

en <strong>la</strong> parte obligatoria.<br />

Lista <strong>de</strong> funcionalida<strong>de</strong>s opcionales que se hayan implementado, y breve<br />

<strong>de</strong>scripción <strong>de</strong> cada una.<br />

url <strong>de</strong>l vi<strong>de</strong>o <strong>de</strong>mostración <strong>de</strong> <strong>la</strong> funcionalidad básica<br />

url <strong>de</strong>l vi<strong>de</strong>o <strong>de</strong>mostración <strong>de</strong> <strong>la</strong> funcionalidad optativa, si se ha realizado<br />

funcionalidad optativa<br />

El fichero README se incluirá también como comentario en el recurso <strong>de</strong><br />

subida <strong>de</strong> <strong>la</strong> práctica, asegurándose <strong>de</strong> que <strong>la</strong>s urls incluidas en él son en<strong>la</strong>ces<br />

“pinchables”.<br />

60


Los vi<strong>de</strong>os <strong>de</strong> <strong>de</strong>mostración serán <strong>de</strong> una duración máxima <strong>de</strong> 2 minutos (cada<br />

uno), y consistirán en una captura <strong>de</strong> pantal<strong>la</strong> <strong>de</strong> un navegador web utilizando <strong>la</strong><br />

aplicación, y mostrando lo mejor posible <strong>la</strong> funcionalidad correspondiente (básica<br />

u opcional). Siempre que sea posible, el alumno comentará en el audio <strong>de</strong>l vi<strong>de</strong>o<br />

lo que vaya ocurriendo en <strong>la</strong> captura. Los vi<strong>de</strong>os se colocarán en algún servicio <strong>de</strong><br />

subida <strong>de</strong> vi<strong>de</strong>os en Internet (por ejemplo, Vimeo o YouTube).<br />

Hay muchas herramientas que permiten realizar <strong>la</strong> captura <strong>de</strong> pantal<strong>la</strong>. Por<br />

ejemplo, en GNU/Linux pue<strong>de</strong> usarse Gtk-RecordMyDesktop o Istanbul (ambas<br />

disponibles en Ubuntu). Es importante que <strong>la</strong> captura sea realizada <strong>de</strong> forma que<br />

se distinga razonablemente lo que se grabe en el vi<strong>de</strong>o.<br />

En caso <strong>de</strong> que convenga editar el vi<strong>de</strong>o resultante (por ejemplo, para eliminar<br />

tiempos <strong>de</strong> espera) pue<strong>de</strong> usarse un editor <strong>de</strong> vi<strong>de</strong>o, pero siempre <strong>de</strong>berá ser<br />

indicado que se ha hecho tal cosa con un comentario en el audio, o un texto en el<br />

vi<strong>de</strong>o. Hay muchas herramientas que permiten realizar esta edición. Por ejemplo,<br />

en GNU/Linux pue<strong>de</strong> usarse OpenShot o PiTiVi.<br />

17.6. Notas y comentarios<br />

La práctica <strong>de</strong>berá funcionar en el entorno GNU/Linux (Ubuntu) <strong>de</strong>l <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, con <strong>la</strong> versión <strong>de</strong> Django insta<strong>la</strong>da en /usr/local/django<br />

(Django 1.3.1).<br />

La práctica <strong>de</strong>berá funcionar <strong>de</strong>s<strong>de</strong> el navegador Firefox disponible en el <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Se recomienda construir una o varias aplicaciones complementarias para probar<br />

<strong>la</strong> <strong>de</strong>scarga y almacenamiento en base <strong>de</strong> datos <strong>de</strong> los canales que alimentarán el<br />

p<strong>la</strong>neta.<br />

18. Ejercicios complementarios <strong>de</strong> varios temas<br />

A continuación, algunos ejercicios re<strong>la</strong>cionados con el temario <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Algunos <strong>de</strong> ellos han sido propuestos en exámenes <strong>de</strong> ediciones previas, o en<br />

<strong>asignatura</strong>s con temarios simi<strong>la</strong>res.<br />

18.1. Ejercicio 1<br />

Se pi<strong>de</strong> realizar una aplicación web que, dado un número, calcule si es primo o<br />

no. El número se indica como recurso, con URLs <strong>de</strong> <strong>la</strong> forma http://primos.org/34<br />

(si el número a probar es “34”). Para esta aplicación:<br />

1. Escribir <strong>la</strong> petición y <strong>la</strong> respuesta HTTP que se podría observar para el caso<br />

<strong>de</strong> que se pruebe el número 34.<br />

61


2. Escribir el código <strong>de</strong> <strong>la</strong> aplicación (sin usar un entorno <strong>de</strong> <strong>de</strong>sarrollo <strong>de</strong> aplicaciones<br />

web). Escribir el código en Python, pseudo-Python o pseudocódigo.<br />

Pue<strong>de</strong> usarse un método “IsPrime”, que acepta un número como parámetro,<br />

y <strong>de</strong>vuelve True si ese número es primo, y False en caso contrario.<br />

3. Se quiere que <strong>la</strong> aplicación mantenga una caché <strong>de</strong> los números ya probados,<br />

para evitar volver a probar un número si ya se calculó si era primo. Explicar<br />

<strong>la</strong>s modificaciones que se verán en el intercambio HTTP, y en el código <strong>de</strong><br />

<strong>la</strong> aplicación.<br />

4. Se quiere que <strong>la</strong> aplicación, tal y como <strong>la</strong> <strong>de</strong>scribía el enunciado al principio<br />

<strong>de</strong> este ejercicio, siga funcionado en presencia <strong>de</strong> caídas y posteriores<br />

recuperaciones <strong>de</strong>l servidor. ¿Qué cambios habrá que hacerle<br />

5. Lo mismo, en el caso <strong>de</strong> <strong>la</strong> aplicación con caché, tal y como se <strong>de</strong>scribe dos<br />

aparatados más arriba.<br />

18.2. Ejercicio 2<br />

Una aplicación web dada permite el acceso a cierto recurso, “/resource”, sólo a<br />

usuarios que se hayan autenticado previamente. Los usuarios se autentican mediante<br />

nombre <strong>de</strong> usuario y contraseña. La autenticación se realiza mediante POST a<br />

un recurso “/login”. Ese mismo recurso, si recibe un GET, sirve un formu<strong>la</strong>rio para<br />

po<strong>de</strong>r realizar <strong>la</strong> autenticación. En este caso, se p<strong>la</strong>ntean <strong>la</strong>s siguientes preguntas:<br />

1. Describir (indicando <strong>la</strong>s cabeceras relevantes y el contenido <strong>de</strong>l cuerpo <strong>de</strong> los<br />

mensajes) <strong>la</strong>s interacciones HTTP, <strong>de</strong>s<strong>de</strong> que un usuario se quiere autenticar,<br />

y pincha en <strong>la</strong> URL para recibir el formu<strong>la</strong>rio, hasta que este usuario recibe<br />

un mensaje <strong>de</strong> bienvenida indicando que está ya autenticado.<br />

2. Escribe el código <strong>de</strong> una vista (view) que <strong>de</strong> servicio al recurso “/login”.<br />

Escríbelo como se haría en una view Django (pero si prefieres, usando pseudo-<br />

Python o pseudocódigo).<br />

3. Describe <strong>la</strong> interacción HTTP que se producirá <strong>de</strong>s<strong>de</strong> que un navegador<br />

invoca <strong>la</strong> un GET sobre “/resource” hasta que recibe <strong>la</strong> pertinente respuesta<br />

<strong>de</strong> <strong>la</strong> aplicación web. Hazlo primero en el caso <strong>de</strong> que el navegador se haya<br />

autenticado previamente como usuario, y luego en caso <strong>de</strong> que no lo haya<br />

hecho.<br />

62


18.3. Ejercicio 3<br />

Te han pedido que diseñes un servicio en Internet para elegir, comentar y<br />

recibir recomendaciones sobre lugares para pasar <strong>la</strong>s vacaciones. Las características<br />

principales <strong>de</strong>l sistema serán:<br />

1. La información, comentarios y recomendaciones siempre estarán referidos a<br />

un lugar (un pueblo, una p<strong>la</strong>ya, una zona).<br />

2. Cualquier usuario <strong>de</strong>l servicio podrá “abrir” un nuevo lugar, simplemente<br />

indicando su nombre y subiendo una <strong>de</strong>scripción <strong>de</strong>l mismo. A partir <strong>de</strong> ese<br />

momento, habrá una URL en el servicio que mostrará esa información. Nos<br />

referiremos a esa URL como “<strong>la</strong> página <strong>de</strong>l lugar”.<br />

3. Cualquier usuario <strong>de</strong>l servicio (incluyendo el que lo abrió) podrá modificar<br />

<strong>la</strong> <strong>de</strong>scripción <strong>de</strong> un lugar y/o añadir un comentario. Los comentarios y los<br />

cambios en <strong>la</strong> <strong>de</strong>scripción se reflejarán inmediatamente en <strong>la</strong> página <strong>de</strong>l lugar<br />

correspondiente.<br />

4. Cualquier usuario <strong>de</strong>l servicio podrá “elegir” un lugar. Para ello, tendrá un<br />

botón que podrá pulsar en <strong>la</strong> página <strong>de</strong> ese lugar.<br />

5. Cualquier usuario <strong>de</strong>l servicio podrá pedir que se le recomien<strong>de</strong> un lugar,<br />

según <strong>la</strong>s elecciones pasadas propias y <strong>de</strong> otros usuarios. El algoritmo que el<br />

servicio use para realizar estas recomendaciones no es objeto <strong>de</strong>l diseño.<br />

6. No se quieren mantener cuentas <strong>de</strong> usuarios, pero sí se quiere po<strong>de</strong>r diferenciar<br />

entre usuarios diferentes al menos para <strong>la</strong>s elecciones y <strong>la</strong>s recomendaciones<br />

(para que el algoritmo pueda diferenciar entre elecciones propias y<br />

elecciones <strong>de</strong> otros).<br />

7. El sitio ofrecerá, para cada lugar, un canal RSS con los comentarios sobre ese<br />

lugar. También habrá un canal RSS, único para todo el sitio, con los últimos<br />

lugares sobre los que se ha comentado.<br />

Salvo cuando se indique otra cosa, se supone que un usuario correspon<strong>de</strong> con<br />

un navegador en un or<strong>de</strong>nador concreto.<br />

Teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Detal<strong>la</strong> un esquema <strong>de</strong> URLs que permita nombrar, siguiendo en lo posible<br />

el diseño REST, todos los elementos <strong>de</strong>l servicio. Procura no usar URLs<br />

innecesarias.<br />

63


2. Describe todas <strong>la</strong>s interacciones HTTP que tendrán lugar en el sistema para<br />

abrir un lugar. Detal<strong>la</strong> <strong>la</strong>s URLs implicadas, e indica <strong>la</strong>s cabeceras más<br />

relevantes.<br />

3. I<strong>de</strong>m para realizar un comentario sobre un lugar. En <strong>la</strong> página <strong>de</strong>l lugar<br />

habrá un formu<strong>la</strong>rio para poner comentarios, el usuario lo rellenará y a continuación<br />

lo verá en esa misma página <strong>de</strong>l lugar (no se usa AJAX en este<br />

apartado).<br />

4. I<strong>de</strong>m para elegir un lugar. El usuario habrá <strong>de</strong> estar a <strong>la</strong> vista <strong>de</strong>l lugar que<br />

quiere elegir, y una vez elegido, tendrá que verlo como elegido en esa misma<br />

página (no se usa AJAX en este apartado).<br />

5. Cuando un usuario cambie <strong>de</strong> navegador, querrá seguir siendo reconocido<br />

por el sistema. Diseña un mecanismo, lo más simple posible, que le permita<br />

hacerlo, manteniendo garantías <strong>de</strong> que quien no tenga acceso a su navegador<br />

no podrá colocarse en su lugar <strong>de</strong>s<strong>de</strong> otro. Si es posible, diséñalo sin usar el<br />

correo electrónico.<br />

6. Describe los cambios que habría que hacer al sistema para que en <strong>la</strong> página<br />

<strong>de</strong> cada lugar cualquier usuario pueda, a<strong>de</strong>más <strong>de</strong> comentarios, subir fotos.<br />

7. Describe los cambios que habría que hacer en el sistema para que <strong>la</strong> elección<br />

<strong>de</strong> un lugar se pudiera expresar sin que se produzca una recarga <strong>de</strong> página,<br />

usando AJAX.<br />

8. ¿Se podría construir un gadget, para integrar en un mashup, que mostrase los<br />

últimos comentarios que se están poniendo en el servicio Explica qué partes<br />

<strong>de</strong>l servicio especificado en <strong>la</strong> primera parte <strong>de</strong>l ejercicio usarías, y si es caso,<br />

qué modificaciones <strong>de</strong>l servicio harían falta.<br />

18.4. Ejercicio 4<br />

Se <strong>de</strong>ci<strong>de</strong> construir un sitio para permitir que sus usuarios realicen anotaciones<br />

geolocalizadas que puedan ser consultadas por otros usuarios. Las características<br />

principales <strong>de</strong>l sistema serán:<br />

1. Cualquier usuario <strong>de</strong>l sitio podrá subir una anotación geolocalizada. Para<br />

ello, rellenará un formu<strong>la</strong>rio en su navegador en el que especificará el texto<br />

que constituirá <strong>la</strong> anotación y sus coor<strong>de</strong>nadas (<strong>la</strong>titud y longitud).<br />

2. Cualquier usuario podrá consultar información geolocalizada, <strong>de</strong> varias formas:<br />

64


Especificando unas coor<strong>de</strong>nadas (<strong>la</strong>titud y longitud) y una distancia en<br />

un formu<strong>la</strong>rio en el navegador. El sistema <strong>de</strong>volverá una página HTML<br />

con todas <strong>la</strong>s anotaciones (incluyendo sus coor<strong>de</strong>nadas y el texto correspondiente)<br />

que estén cerca <strong>de</strong> <strong>la</strong>s coor<strong>de</strong>nadas especificadas (a menos<br />

<strong>de</strong> <strong>la</strong> distancia indicada).<br />

Especificando unas coor<strong>de</strong>nadas (<strong>la</strong>titud y longitud) y una distancia<br />

como parte <strong>de</strong> una URL <strong>de</strong>l servicio, y obteniendo como respuesta un<br />

canal GeoRSS con todas <strong>la</strong>s anotaciones (incluyendo sus coor<strong>de</strong>nadas y<br />

el texto correspondiente) que estén cerca <strong>de</strong> <strong>la</strong>s coor<strong>de</strong>nadas especificadas<br />

(a menos <strong>de</strong> <strong>la</strong> distancia indicada).<br />

Especificando unas coor<strong>de</strong>nadas (<strong>la</strong>titud y longitud) y una distancia<br />

como parte <strong>de</strong> una URL <strong>de</strong>l servicio, y obteniendo como respuesta un<br />

mapa con los puntos anotados (en formato PNG).<br />

Especificando una ca<strong>de</strong>na <strong>de</strong> texto en un formu<strong>la</strong>rio en el navegador.<br />

El sistema <strong>de</strong>volverá una página HTML con todas <strong>la</strong>s anotaciones (incluyendo<br />

sus coor<strong>de</strong>nadas y el texto correspondiente) que incluyan ese<br />

texto.<br />

3. Los usuarios podrán usar el sitio sin tener que abrir cuenta (<strong>de</strong> hecho, el sitio<br />

no mantendrá cuentas).<br />

4. Cualquier anotación podrá ser editada (para modificar<strong>la</strong> o eliminar<strong>la</strong>) <strong>la</strong>s<br />

veces que se quiera, si se hace <strong>de</strong>s<strong>de</strong> el mismo navegador <strong>de</strong>s<strong>de</strong> el que se<br />

creó.<br />

En particu<strong>la</strong>r, y teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Describe todas <strong>la</strong>s interacciones HTTP que tendrán lugar en el sistema para<br />

crear una anotación. Detal<strong>la</strong> <strong>la</strong>s URLs implicadas, e indica <strong>la</strong>s cabeceras más<br />

relevantes.<br />

2. I<strong>de</strong>m para ver como página HTML <strong>la</strong>s anotaciones cercanas a una posición<br />

dada por sus coor<strong>de</strong>nadas.<br />

3. I<strong>de</strong>m para editar una anotación previamente creada <strong>de</strong>s<strong>de</strong> el mismo navegador.<br />

4. Se quiere que si un usuario pier<strong>de</strong> su or<strong>de</strong>nador, y pasa a usar uno nuevo,<br />

pueda seguir editando <strong>la</strong>s anotaciones que creó. Describe un mecanismo que<br />

lo permita, sin obligar al usuario a crear una cuenta en el sistema.<br />

65


5. Se quiere utilizar el servicio <strong>de</strong> consulta <strong>de</strong> anotaciones <strong>de</strong>s<strong>de</strong> un programa<br />

<strong>de</strong> gestión <strong>de</strong> mapas. El programa ya tiene funcionalidad <strong>de</strong> mostrar mapas,<br />

y <strong>de</strong> mostrar información asociada con un punto cualquiera <strong>de</strong>l mapa. Se<br />

preten<strong>de</strong> que se utilice esta funcionalidad <strong>de</strong> mostrar información para mostrar<br />

<strong>la</strong>s anotaciones. Explicar cómo se podría usar el servicio <strong>de</strong>scrito en <strong>la</strong><br />

primera parte <strong>de</strong> este ejercicio. Indica <strong>la</strong>s URLs y <strong>la</strong>s transacciones HTTP<br />

involucradas (indicando sus principales cabeceras) para que <strong>la</strong> aplicación<br />

pueda mostrar <strong>la</strong>s anotaciones cercanas a un punto <strong>de</strong>l mapa.<br />

6. Indica cómo se podría usar el servicio <strong>de</strong>scrito en <strong>la</strong> primera parte <strong>de</strong>l ejercicio<br />

para que <strong>de</strong>s<strong>de</strong> <strong>la</strong> aplicación <strong>de</strong>l apartado anterior se puedan también crear<br />

anotaciones. ¿Pue<strong>de</strong> <strong>de</strong>cirse que <strong>la</strong> parte <strong>de</strong>l servicio que has usado sigue <strong>la</strong>s<br />

directrices REST<br />

7. Pasado un tiempo se p<strong>la</strong>ntea <strong>la</strong> posibilidad <strong>de</strong> incorporar cuentas <strong>de</strong> usuario<br />

para que estos puedan autenticarse en el sitio web. Describe brevemente 2<br />

mecanismos (en cuanto a interacción navegador-servicio) que podrían usarse<br />

con HTTP para realizar <strong>la</strong> autenticación y <strong>la</strong>s principales ventajas e inconvenientes<br />

<strong>de</strong> cada uno.<br />

19. Prácticas finales <strong>de</strong> cursos pasados<br />

19.1. Práctica final (2010, enero)<br />

La práctica final <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> consiste en <strong>la</strong> creación <strong>de</strong> un p<strong>la</strong>neta, o<br />

agregador <strong>de</strong> canales, como aplicación web. A continuación se <strong>de</strong>scribe el funcionamiento<br />

y arquitectura general <strong>de</strong> <strong>la</strong> aplicación, <strong>la</strong> funcionalidad mínima que <strong>de</strong>be<br />

proporcionar, y otra funcionalidad optativa que podrá tener.<br />

19.1.1. Arquitectura y funcionamiento general<br />

Arquitectura general:<br />

La práctica consistirá en una aplicación web que servirá los datos a los usuarios.<br />

La aplicación web se construirá como un proyecto Django, que incluirá una<br />

o varias aplicaciones Django que implementen <strong>la</strong> funcionalidad requerida.<br />

Para el almacenamiento <strong>de</strong> datos persistente se usará SQLite3, con tab<strong>la</strong>s<br />

<strong>de</strong>finidas según mo<strong>de</strong>los en Django.<br />

66


Se usará <strong>la</strong> aplicación Django “Admin site” para mantener los usuarios con<br />

cuenta en el sistema, y para <strong>la</strong> gestión general <strong>de</strong> <strong>la</strong>s bases <strong>de</strong> datos necesarias.<br />

Se utilizarán p<strong>la</strong>ntil<strong>la</strong>s Django (a ser posible, una jerarquía <strong>de</strong> p<strong>la</strong>ntil<strong>la</strong>s, para<br />

que toda <strong>la</strong> aplicación tenga un aspecto simi<strong>la</strong>r) para <strong>de</strong>finir <strong>la</strong>s páginas que<br />

se servirán a los navegadores <strong>de</strong> los usuarios. Estas p<strong>la</strong>ntil<strong>la</strong>s incluirán en<br />

todas <strong>la</strong>s páginas al menos:<br />

• Un banner (imagen) <strong>de</strong>l sitio, en <strong>la</strong> parte superior.<br />

• Un menú <strong>de</strong> opciones también en <strong>la</strong> parte superior.<br />

• Un pie <strong>de</strong> página con una nota <strong>de</strong> copyright.<br />

Se utilizarán hojas <strong>de</strong> estilo CSS para <strong>de</strong>terminar <strong>la</strong> apariencia <strong>de</strong> <strong>la</strong> aplicación.<br />

Funcionamiento general:<br />

Los usuarios indicarán en qué canales (blogs) están interesados. Para ello,<br />

cada usuario podrá especificar un número en principio ilimitado <strong>de</strong> URLs,<br />

cada una correspondiente a un canal que le interesa.<br />

Cuando un usuario indica que le interesa un blog, se baja el canal correspondiente<br />

y se almacenan en <strong>la</strong> base <strong>de</strong> datos los artículos referenciados en<br />

él.<br />

Cuando un usuario acceda a <strong>la</strong> URL <strong>de</strong> actualización <strong>de</strong> sus blogs, se bajan<br />

los canales correspondientes a todos ellos, y se almacenan en <strong>la</strong> base <strong>de</strong> datos<br />

los artículos correspondientes. Si un artículo ya estaba en <strong>la</strong> base <strong>de</strong> datos,<br />

no <strong>de</strong>be almacenarse dos veces.<br />

Cualquier navegador podrá acce<strong>de</strong>r a <strong>la</strong> interfaz pública <strong>de</strong>l sitio, que ofrecerá<br />

los artículos en <strong>la</strong> base <strong>de</strong> datos e información pública para cada usuario.<br />

Sólo los navegadores con un usuario autenticado podrán personalizar en<br />

qué blogs están interesados.<br />

19.1.2. Funcionalidad mínima<br />

Para cada artículo en <strong>la</strong> base <strong>de</strong> datos <strong>de</strong>l p<strong>la</strong>neta, se mostrarán (salvo que<br />

se indique lo contrario) su título (que será un en<strong>la</strong>ce al artículo en su blog<br />

original), un en<strong>la</strong>ce al blog original que lo incluye, y su contenido (tal y como<br />

venga especificado en el canal).<br />

67


El p<strong>la</strong>neta mostrará en una interfaz pública (visible por cualquiera que no<br />

tenga cuenta en el sitio) todos los artículos que tenga en <strong>la</strong> base <strong>de</strong> datos,<br />

organizados en los siguientes recursos:<br />

• /: Lista <strong>de</strong> los últimos 20 artículos, por fecha <strong>de</strong> publicación, en or<strong>de</strong>n<br />

inverso (más nuevos primero).<br />

• /blog: Lista <strong>de</strong> los últimos 20 artículos <strong>de</strong>l blog “blog”, por fecha <strong>de</strong><br />

publicación, en or<strong>de</strong>n inverso (más nuevos primero).<br />

• /blog/num: Artículo número “num” <strong>de</strong>l blog “blog”, siendo “0” el artículo<br />

más antiguo <strong>de</strong> ese blog que se tiene en <strong>la</strong> base <strong>de</strong> datos.<br />

A<strong>de</strong>más, el p<strong>la</strong>neta mostrará en una interfaz privada (visible sólo para un<br />

usuario concreto cuando se autentica como tal) los artículos que éste haya<br />

seleccionado, organizados en los siguientes recursos:<br />

• /custom: Lista <strong>de</strong> los últimos 20 artículos, por fecha <strong>de</strong> publicación, en<br />

or<strong>de</strong>n inverso (más nuevos primero), <strong>de</strong> los blogs seleccionados por el<br />

usuario.<br />

A<strong>de</strong>más, habrá ciertos recursos don<strong>de</strong> los usuarios registrados podrán (una<br />

vez autenticados) configurar ciertos aspectos <strong>de</strong>l sitio:<br />

• /conf: Configuración <strong>de</strong>l usuario. Incluirá campos para editar su nombre<br />

público, su contraseña (dos veces, para comprobar), y los blogs en los<br />

que está interesado. Estos blogs se podrán elegir bien <strong>de</strong> un menú <strong>de</strong>splegable<br />

(en el que estarán los que ya se están bajando) o indicando sus<br />

datos (<strong>la</strong> URL <strong>de</strong> su canal correspondiente).<br />

• /conf/skin: Configuración <strong>de</strong>l estilo (skin) con el que el usuario quiere<br />

ver el sitio. Mediante un formu<strong>la</strong>rio, el usuario podrá editar el fichero<br />

CSS que codificará su estilo, o podrá copiar el <strong>de</strong> otro usuario. Cada<br />

usuario tendrá un estilo (fichero CSS) por <strong>de</strong>fecto, que el sistema le<br />

asignará si no lo ha configurado.<br />

• /update: Actualizará los artículos <strong>de</strong> los blogs en los que está interesado<br />

el usuario.<br />

Para cada usuario, se mantendrán ciertos recursos públicos con información<br />

re<strong>la</strong>cionada con ellos:<br />

• /user: Nombre <strong>de</strong> usuario y lista <strong>de</strong> blogs que interesan al usuario<br />

“user”.<br />

68


• /user/feed: Canal RSS con los 20 últimos artículos que interesan al<br />

usuario “user”.<br />

El idioma <strong>de</strong> <strong>la</strong> interfaz <strong>de</strong> usuario <strong>de</strong>l p<strong>la</strong>neta tendrá en cuenta lo que especifique<br />

el navegador, y podrá ser especificado también en <strong>la</strong> URL /conf para<br />

los usuarios registrados (entre opciones para indicar un idioma particu<strong>la</strong>r, o<br />

“por <strong>de</strong>fecto”, que respetará lo que indique el navegador).<br />

19.1.3. Funcionalidad optativa<br />

De forma optativa, se podrá incluir cualquier funcionalidad relevante en el<br />

contexto <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>. Se valorarán especialmente <strong>la</strong>s funcionalida<strong>de</strong>s que impliquen<br />

el uso <strong>de</strong> técnicas nuevas, o <strong>de</strong> aspectos <strong>de</strong> Django no utilizados en los<br />

ejercicios previos, y que tengan sentido en el contexto <strong>de</strong> esta práctica y <strong>de</strong> <strong>la</strong><br />

<strong>asignatura</strong>.<br />

Sólo a modo <strong>de</strong> sugerencia, se incluyen algunas posibles funcionalida<strong>de</strong>s optativas:<br />

Uso <strong>de</strong> AJAX para algún aspecto <strong>de</strong> <strong>la</strong> práctica (por ejemplo, para elegir un<br />

nuevo blog, o para subir comentarios)<br />

Puntuación <strong>de</strong> artículos. Cada usuario registrado pue<strong>de</strong> puntuar cualquier<br />

artículo <strong>de</strong>l sitio, por ejemplo entre 1 y 5. Estas puntuaciones se podrán ver<br />

luego junto al artículo en cuestión.<br />

Comentarios a artículos. Cada usuario registrado pue<strong>de</strong> comentar cualquier<br />

artículo <strong>de</strong>l sitio. Estos comentarios se podrán ver luego junto al artículo en<br />

cuestión (en <strong>la</strong> página <strong>de</strong> ese artículo).<br />

Soporte para logos. Cada blog o artículo <strong>de</strong> un blog se presentará junto con<br />

un logo que represente al blog en cuestión.<br />

Auto<strong>de</strong>scubrimiento <strong>de</strong> canales. Dada una URL (<strong>de</strong> un blog, por ejemplo),<br />

busca si en el<strong>la</strong> hay algún en<strong>la</strong>ce que parece un canal. Si es así, ofrécelo<br />

al usuario para que lo pueda elegir. Esto se pue<strong>de</strong> usar, por ejemplo, en <strong>la</strong><br />

página <strong>de</strong> configuración <strong>de</strong> usuario, como una opción más para elegir canales<br />

(“especifica un blog para buscar sus canales”).<br />

19.1.4. Entrega <strong>de</strong> <strong>la</strong> práctica<br />

La práctica se entregará el día <strong>de</strong>l examen <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, o un día posterior<br />

si así se acordase. La entrega se realizará presencialmente, en el <strong>la</strong>boratorio don<strong>de</strong><br />

tienen lugar <strong>la</strong>s c<strong>la</strong>ses <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> habitualmente.<br />

69


Cada alumno entregará su práctica en un fichero tar.gz, que tendrá preparado<br />

antes <strong>de</strong>l comienzo <strong>de</strong>l examen, y cuya localización mostrará al profesor durante<br />

el transcurso <strong>de</strong>l mismo. El fichero se habrá <strong>de</strong> l<strong>la</strong>mar practica-user.tar.gz, siendo<br />

“user” el nombre <strong>de</strong> <strong>la</strong> cuenta <strong>de</strong>l alumno en el <strong>la</strong>boratorio.<br />

El fichero que se entregue <strong>de</strong>berá constar <strong>de</strong> un proyecto Django completo y<br />

listo para funcionar en el entorno <strong>de</strong>l <strong>la</strong>boratorio, incluyendo <strong>la</strong> base <strong>de</strong> datos con<br />

datos suficientes como para po<strong>de</strong>r probarlo. Estos datos incluirán al menos tres<br />

usuarios, y cinco blogs con sus noticias correspondientes. Se incluirá también un<br />

fichero README con los siguientes datos:<br />

Nombre <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Nombre completo <strong>de</strong>l alumno.<br />

Nombre <strong>de</strong> su cuenta en el <strong>la</strong>boratorio.<br />

Nombres y contraseñas <strong>de</strong> los usuarios creados para <strong>la</strong> práctica.<br />

Resumen <strong>de</strong> <strong>la</strong>s peculiarida<strong>de</strong>s que se quieran mencionar sobre lo implementado<br />

en <strong>la</strong> parte obligatoria.<br />

Lista <strong>de</strong> funcionalida<strong>de</strong>s opcionales que se hayan implementado, y breve<br />

<strong>de</strong>scripción <strong>de</strong> cada una.<br />

19.1.5. Notas y comentarios<br />

La práctica <strong>de</strong>berá funcionar en el entorno GNU/Linux (Ubuntu) <strong>de</strong>l <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, con <strong>la</strong> versión <strong>de</strong> Django insta<strong>la</strong>da en /usr/local/django<br />

(Django 1.1.1).<br />

La práctica <strong>de</strong>berá funcionar <strong>de</strong>s<strong>de</strong> el navegador Firefox disponible en el <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Se recomienda construir una o varias aplicaciones complementarias para probar<br />

<strong>la</strong> <strong>de</strong>scarga y almacenamiento en base <strong>de</strong> datos <strong>de</strong> los canales que alimentarán el<br />

p<strong>la</strong>neta.<br />

Los canales (feeds) RSS que produce <strong>la</strong> aplicación web realizada en <strong>la</strong> práctica<br />

<strong>de</strong>berán funcionar al menos con el agregador Liferea.<br />

19.2. Práctica final (2010, junio)<br />

La práctica final para entrega en <strong>la</strong> convocatoria extraordinaria <strong>de</strong> junio será simi<strong>la</strong>r<br />

a <strong>la</strong> especificada para <strong>la</strong> convocatoria ordinaria <strong>de</strong> enero. En particu<strong>la</strong>r,<br />

<strong>de</strong>berá cumplir <strong>la</strong>s siguientes condiciones:<br />

70


La arquitectura general será <strong>la</strong> misma, salvo:<br />

• En lugar <strong>de</strong> incluir en <strong>la</strong>s p<strong>la</strong>ntil<strong>la</strong>s Django un menú <strong>de</strong> opciones en <strong>la</strong><br />

parte superior <strong>de</strong> <strong>la</strong>s páginas, ese menú estará en una columna en <strong>la</strong><br />

parte <strong>de</strong>recha <strong>de</strong> cada página.<br />

El funcionamiento general será el mismo, salvo:<br />

• Cuando un usuario indica que le interesa un blog, no se almacenan en<br />

<strong>la</strong> base <strong>de</strong> datos los artículos <strong>de</strong> ese blog.<br />

• No habrá URL <strong>de</strong> actualización <strong>de</strong> los blogs <strong>de</strong> un usuario.<br />

• Los artículos correspondientes a un blog se actualizarán sólo cuando se<br />

visualice una página <strong>de</strong>l p<strong>la</strong>neta que incluya artículos <strong>de</strong> ese blog. En<br />

ese momento, los artículos nuevos (los que no estaban ya en <strong>la</strong> base <strong>de</strong><br />

datos) se bajarán a dicha base <strong>de</strong> datos.<br />

La funcionalidad mínima será <strong>la</strong> misma, salvo:<br />

• No se implementará el recurso “/update”, dado que el funcionamiento<br />

<strong>de</strong> <strong>la</strong> actualización será diferente, como se ha indicado anteriormente.<br />

• El recurso “/user” incluirá <strong>la</strong> lista <strong>de</strong> los últimos 20 artículos, por fecha<br />

<strong>de</strong> publicación, en or<strong>de</strong>n inverso (más nuevos primero), <strong>de</strong> los blogs<br />

seleccionados por el usuario, a<strong>de</strong>más <strong>de</strong>l nombre <strong>de</strong> usuario.<br />

• Cada usuario registrado podrá puntuar cualquier artículo <strong>de</strong>l sitio entre<br />

1 y 5. Estas puntuaciones se podrán ver junto al artículo en cuestión,<br />

en todos los sitios don<strong>de</strong> aparece un en<strong>la</strong>ce a él en el p<strong>la</strong>neta.<br />

La funcionalidad optativa será <strong>la</strong> misma, salvo <strong>la</strong> puntuación <strong>de</strong> artículos,<br />

que ya ha sido mencionada como funcionalidad mínima.<br />

El resto <strong>de</strong> condiciones serán iguales que en <strong>la</strong> convocatoria <strong>de</strong> enero <strong>de</strong> 2010.<br />

19.3. Práctica final (2010, diciembre)<br />

La entrega <strong>de</strong> esta práctica será necesaria para po<strong>de</strong>r optar a aprobar <strong>la</strong> <strong>asignatura</strong>.<br />

Este enunciado correspon<strong>de</strong> con <strong>la</strong> convocatoria <strong>de</strong> diciembre.<br />

La práctica final <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> consiste en <strong>la</strong> creación <strong>de</strong> una aplicación web<br />

<strong>de</strong> resumen y cache <strong>de</strong> micronotas (microblogs). En este enunciado, l<strong>la</strong>maremos a<br />

esa aplicación “MiResumen”, y a los resúmenes <strong>de</strong> micronotas para cada usuario,<br />

“microresumen”.<br />

71


Los sitios <strong>de</strong> microblogs permiten a sus usuarios compartir notas breves (habitualmente<br />

<strong>de</strong> 140 caracteres o menos). Entre los más popu<strong>la</strong>res pue<strong>de</strong>n mencionarse<br />

Twitter 3 e I<strong>de</strong>nti.ca 4 . La aplicación web a realizar se encargará <strong>de</strong> mostrar <strong>la</strong>s<br />

micronotas que se indiquen, junto con información re<strong>la</strong>cionada. A continuación se<br />

<strong>de</strong>scribe el funcionamiento y arquitectura general <strong>de</strong> <strong>la</strong> aplicación, <strong>la</strong> funcionalidad<br />

mínima que <strong>de</strong>be proporcionar, y otra funcionalidad optativa que podrá tener.<br />

19.3.1. Arquitectura y funcionamiento general<br />

Arquitectura general:<br />

La práctica consistirá en una aplicación web que servirá los datos a los usuarios.<br />

La aplicación web se construirá como un proyecto Django, que incluirá una<br />

o varias aplicaciones Django que implementen <strong>la</strong> funcionalidad requerida.<br />

Para el almacenamiento <strong>de</strong> datos persistente se usará SQLite3, con tab<strong>la</strong>s<br />

<strong>de</strong>finidas según mo<strong>de</strong>los en Django.<br />

Se usará <strong>la</strong> aplicación Django “Admin site” para mantener los usuarios con<br />

cuenta en el sistema, y para <strong>la</strong> gestión general <strong>de</strong> <strong>la</strong>s bases <strong>de</strong> datos necesarias.<br />

Se utilizarán p<strong>la</strong>ntil<strong>la</strong>s Django (a ser posible, una jerarquía <strong>de</strong> p<strong>la</strong>ntil<strong>la</strong>s, para<br />

que toda <strong>la</strong> aplicación tenga un aspecto simi<strong>la</strong>r) para <strong>de</strong>finir <strong>la</strong>s páginas que<br />

se servirán a los navegadores <strong>de</strong> los usuarios. Estas p<strong>la</strong>ntil<strong>la</strong>s incluirán en<br />

todas <strong>la</strong>s páginas al menos:<br />

• Un banner (imagen) <strong>de</strong>l sitio, en <strong>la</strong> parte superior.<br />

• Un menú <strong>de</strong> opciones también en <strong>la</strong> parte superior, a <strong>la</strong> <strong>de</strong>recha <strong>de</strong>l<br />

banner <strong>de</strong>l sitio.<br />

• Un pie <strong>de</strong> página con una nota <strong>de</strong> copyright.<br />

Se utilizarán hojas <strong>de</strong> estilo CSS para <strong>de</strong>terminar <strong>la</strong> apariencia <strong>de</strong> <strong>la</strong> aplicación.<br />

Funcionamiento general:<br />

Se consi<strong>de</strong>rarán sólo micronotas en I<strong>de</strong>nti.ca. L<strong>la</strong>maremos a los usuarios <strong>de</strong><br />

I<strong>de</strong>nti.ca “micronoteros”.<br />

3 http://twitter.com<br />

4 http://i<strong>de</strong>nti.ca<br />

72


MiResumen mantendrá usuarios, que habrán <strong>de</strong> autenticarse para po<strong>de</strong>r configurar<br />

<strong>la</strong> aplicación.<br />

Cada usuario <strong>de</strong> MiResumen indicará qué micronoteros <strong>de</strong> I<strong>de</strong>nti.ca le interesan,<br />

configurando una lista <strong>de</strong> micronoteros.<br />

Cuando un usuario indica que le interesa un micronotero, MiResumen bajará<br />

el canal RSS correspondiente, y se almacenarán en <strong>la</strong> base <strong>de</strong> datos <strong>la</strong>s<br />

micronotas referenciadas en él.<br />

Cuando un usuario acceda a <strong>la</strong> URL <strong>de</strong> actualización <strong>de</strong> su microresumen, se<br />

bajan los canales correspondientes a todos los micronoteros que tiene especificados,<br />

y se almacenan en <strong>la</strong> base <strong>de</strong> datos <strong>la</strong>s micronotas correspondientes.<br />

Si una micronota ya estaba en <strong>la</strong> base <strong>de</strong> datos, no <strong>de</strong>be almacenarse dos<br />

veces.<br />

Cualquier navegador podrá acce<strong>de</strong>r a <strong>la</strong> interfaz pública <strong>de</strong>l sitio, que ofrecerá<br />

los microresúmenes <strong>de</strong> cada usuario.<br />

19.3.2. Funcionalidad mínima<br />

Para cada micronota en <strong>la</strong> base <strong>de</strong> datos <strong>de</strong>l p<strong>la</strong>neta, se mostrarán (salvo que<br />

se indique lo contrario) su texto, un en<strong>la</strong>ce a <strong>la</strong> micronota en I<strong>de</strong>nti.ca, el<br />

nombre <strong>de</strong>l micronotero que <strong>la</strong> puso (con un en<strong>la</strong>ce a su página en I<strong>de</strong>nti.ca),<br />

y <strong>la</strong> fecha en que <strong>la</strong> puso,<br />

MiResumen mostrará en una interfaz pública (visible por cualquiera que no<br />

tenga cuenta en el sitio) todas <strong>la</strong>s micronotas que tenga en <strong>la</strong> base <strong>de</strong> datos,<br />

organizadas en los siguientes recursos:<br />

• /: Microresumen <strong>de</strong> <strong>la</strong>s últimas 50 micronoticias, or<strong>de</strong>nadas por fecha<br />

inversa <strong>de</strong> publicación, en or<strong>de</strong>n inverso (más nuevos primero).<br />

• /noteros/micronotero: Microresumen <strong>de</strong> <strong>la</strong>s últimas 50 micronoticias <strong>de</strong>l<br />

micronotero “micronotero”, or<strong>de</strong>nadas por fecha inversa <strong>de</strong> publicación,<br />

en or<strong>de</strong>n inverso (más nuevos primero).<br />

• /usuarios/usuario: Microresumen <strong>de</strong> <strong>la</strong>s últimas 50 micronoticias <strong>de</strong> los<br />

micronoteros que sigue el usuario “usuario”, or<strong>de</strong>nadas por fecha inversa<br />

<strong>de</strong> publicación.<br />

• /usuarios/usuario/feed: Canal RSS con <strong>la</strong>s 50 últimas micronotas que<br />

interesan al usuario “usuario”.<br />

A<strong>de</strong>más MiResumen proporcionará ciertos recursos don<strong>de</strong> los usuarios registrados<br />

podrán (una vez autenticados) configurar ciertos aspectos <strong>de</strong>l sitio:<br />

73


• /conf: Configuración <strong>de</strong>l usuario. Incluirá campos para editar su nombre<br />

público, su contraseña (dos veces, para comprobar), y el idioma que<br />

prefiere (al menos <strong>de</strong>berá po<strong>de</strong>r elegir entre español e inglés).<br />

• /conf/skin: Configuración <strong>de</strong>l estilo (skin) con el que el usuario quiere<br />

ver el sitio. Mediante un formu<strong>la</strong>rio, el usuario podrá editar el fichero<br />

CSS que codificará su estilo, o podrá copiar el <strong>de</strong> otro usuario. Cada<br />

usuario tendrá un estilo (fichero CSS) por <strong>de</strong>fecto, que el sistema le<br />

asignará si no lo ha configurado.<br />

• /micronoteros: Lista <strong>de</strong> los micronoteros seleccionados por el usuario,<br />

junto con en<strong>la</strong>ce a su página en I<strong>de</strong>nti.ca. El usuario podrá eliminar un<br />

micronotero <strong>de</strong> <strong>la</strong> lista, o añadir uno nuevo mediante POST sobre ese<br />

recurso. Los micronoteros se podrán elegir bien <strong>de</strong> un menú <strong>de</strong>splegable<br />

(en el que estarán los que tiene seleccionados cualquier usuario <strong>de</strong><br />

MiResumen) o indicando su nombre <strong>de</strong> micronotero en I<strong>de</strong>nti.ca.<br />

• /update: Actualizará <strong>la</strong>s micronotas <strong>de</strong> los micronoteros en los que<br />

está interesado el usuario.<br />

El idioma <strong>de</strong> <strong>la</strong> interfaz <strong>de</strong> usuario <strong>de</strong>l p<strong>la</strong>neta será el especificado en <strong>la</strong><br />

URL /conf para los usuarios registrados. Para los visitantes no registrados,<br />

será español.<br />

Para <strong>la</strong> generación <strong>de</strong> canales RSS y para <strong>la</strong> internacionalización se podrán<br />

usar los mecanismos que proporciona Django, o no, según el alumno consi<strong>de</strong>re que<br />

le sea más conveniente.<br />

19.3.3. Funcionalidad optativa<br />

De forma optativa, se podrá incluir cualquier funcionalidad relevante en el<br />

contexto <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>. Se valorarán especialmente <strong>la</strong>s funcionalida<strong>de</strong>s que impliquen<br />

el uso <strong>de</strong> técnicas nuevas, o <strong>de</strong> aspectos <strong>de</strong> Django no utilizados en los<br />

ejercicios previos, y que tengan sentido en el contexto <strong>de</strong> esta práctica y <strong>de</strong> <strong>la</strong><br />

<strong>asignatura</strong>.<br />

Sólo a modo <strong>de</strong> sugerencia, se incluyen algunas posibles funcionalida<strong>de</strong>s optativas:<br />

Uso <strong>de</strong> Ajax para algún aspecto <strong>de</strong> <strong>la</strong> práctica (por ejemplo, para solicitar<br />

actualización <strong>de</strong> <strong>la</strong> lista <strong>de</strong> micronotas, o para suscribirse a un micronotero<br />

picando sobre una micronota suya).<br />

Promoción <strong>de</strong> micronotas. Cada usuario registrado pue<strong>de</strong> promocionar (indicar<br />

que le gusta) cualquier micronota <strong>de</strong>l sitio. Cada micronota se verá en<br />

el sitio junto con el número <strong>de</strong> promociones que ha recibido.<br />

74


Soporte para avatares. Cada micronota se presentará junto con el avatar<br />

(imagen) correspondiente al micronotero que <strong>la</strong> ha puesto.<br />

Soporte para Twitter y/o otros sitios <strong>de</strong> microblogging (micronotas) a<strong>de</strong>más<br />

<strong>de</strong> I<strong>de</strong>nti.ca<br />

En<strong>la</strong>ce a URLs. Se i<strong>de</strong>ntificarán en <strong>la</strong>s micronotas los textos que tengan<br />

formato <strong>de</strong> URL, y se mostrará esa URL como en<strong>la</strong>ce.<br />

En<strong>la</strong>ce a micronoteros referenciados. Se i<strong>de</strong>ntificarán en <strong>la</strong>s micronotas los<br />

textos que tengan formato <strong>de</strong> i<strong>de</strong>ntificador <strong>de</strong> micronotero (@nombre), y se<br />

mostrarán como en<strong>la</strong>ce a <strong>la</strong> página <strong>de</strong>l micronotero en cuestión.<br />

Suscripción a los mismos micronoteros a los que esté suscrito otro usuario. Un<br />

usuario podrá indicar que quiere suscribirse a <strong>la</strong> misma lista <strong>de</strong> micronoteros<br />

que otro, indicando sólo su i<strong>de</strong>ntificador <strong>de</strong> usuario.<br />

19.3.4. Entrega <strong>de</strong> <strong>la</strong> práctica<br />

La práctica se entregará electrónicamente en una <strong>de</strong> <strong>la</strong>s dos fechas indicadas:<br />

El día anterior al examen <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, esto es, el 12 <strong>de</strong> diciembre, a <strong>la</strong>s<br />

18:00.<br />

El 30 <strong>de</strong> diciembre a <strong>la</strong>s 23:00.<br />

A<strong>de</strong>más, los alumnos que hayan presentado <strong>la</strong>s prácticas podrán tener que<br />

realizar una entrega presencial en una <strong>de</strong> <strong>la</strong>s dos fechas indicadas:<br />

El día <strong>de</strong>l examen, esto es, el 14 <strong>de</strong> diciembre, al terminar el examen <strong>de</strong><br />

teoría. La lista <strong>de</strong> alumnos que tengan que hacer <strong>la</strong> entrega presencial se<br />

indicará durante el examen <strong>de</strong> teoría.<br />

El día 10 <strong>de</strong> enero, a <strong>la</strong>s 16:00. La lista <strong>de</strong> alumnos que tengan que hacer <strong>la</strong><br />

entrega presencial se indicará con anterioridad en el sito web <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

La entrega presencial se realizará en el <strong>la</strong>boratorio don<strong>de</strong> tienen lugar habitualmente<br />

<strong>la</strong>s c<strong>la</strong>ses <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Cada alumno entregará su práctica colocándo<strong>la</strong> en un directorio en su cuenta<br />

en el <strong>la</strong>boratorio. El directorio, que <strong>de</strong>berá colgar directamente <strong>de</strong> su directorio<br />

hogar ($HOME), se l<strong>la</strong>mará “pf django 2010”.<br />

El directorio que se entregue <strong>de</strong>berá constar <strong>de</strong> un proyecto Django completo<br />

y listo para funcionar en el entorno <strong>de</strong>l <strong>la</strong>boratorio, incluyendo <strong>la</strong> base <strong>de</strong> datos<br />

con datos suficientes como para po<strong>de</strong>r probarlo. Estos datos incluirán al menos<br />

tres usuarios, y cinco micronoteros con sus micronotas correspondientes. Entre los<br />

usuarios, habrá en <strong>la</strong> base <strong>de</strong> datos al menos los dos siguientes.<br />

75


Usuario “pepe”, contraseña “XXX”<br />

Usuario “pepa”, contraseña “XXX”<br />

Cada uno <strong>de</strong> estos usuarios estará ya siguiendo al menos dos micronoteros.<br />

Se incluirá también en el directorio que se entregue un fichero README con<br />

los siguientes datos:<br />

Nombre <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Nombre completo <strong>de</strong>l alumno.<br />

Nombre <strong>de</strong> su cuenta en el <strong>la</strong>boratorio.<br />

Nombres y contraseñas <strong>de</strong> los usuarios creados para <strong>la</strong> práctica.<br />

Nombres <strong>de</strong> al menos cinco micronoteros cuyas noticias estén en <strong>la</strong> base <strong>de</strong><br />

datos <strong>de</strong> <strong>la</strong> aplicación.<br />

Resumen <strong>de</strong> <strong>la</strong>s peculiarida<strong>de</strong>s que se quieran mencionar sobre lo implementado<br />

en <strong>la</strong> parte obligatoria.<br />

Lista <strong>de</strong> funcionalida<strong>de</strong>s opcionales que se hayan implementado, y breve<br />

<strong>de</strong>scripción <strong>de</strong> cada una.<br />

Es importante que estas normas se cump<strong>la</strong>n estrictamente, y <strong>de</strong> forma especial<br />

lo que se refiere al nombre <strong>de</strong>l directorio, porque <strong>la</strong> recogida <strong>de</strong> <strong>la</strong>s prácticas, y<br />

parcialmente su prueba, se hará con herramientas automáticas.<br />

[Las normas <strong>de</strong> entrega podrán incluir más <strong>de</strong>talles en el futuro, compruéba<strong>la</strong>s<br />

antes <strong>de</strong> realizar <strong>la</strong> entrega.]<br />

19.3.5. Notas y comentarios<br />

La práctica <strong>de</strong>berá funcionar en el entorno GNU/Linux (Ubuntu) <strong>de</strong>l <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, con <strong>la</strong> versión 1.2.3 <strong>de</strong> Django.<br />

La práctica <strong>de</strong>berá funcionar <strong>de</strong>s<strong>de</strong> el navegador Firefox disponible en el <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Se recomienda construir una o varias aplicaciones complementarias para probar<br />

<strong>la</strong> <strong>de</strong>scarga y almacenamiento en base <strong>de</strong> datos <strong>de</strong> los canales que alimentarán<br />

MiResumen.<br />

Los canales (feeds) RSS que produce <strong>la</strong> aplicación web realizada en <strong>la</strong> práctica<br />

<strong>de</strong>berán funcionar al menos con el agregador Liferea y el que lleva integrado<br />

Firefox.<br />

76


19.3.6. Notas <strong>de</strong> ayuda<br />

A continuación, algunas notas que podrían ayudar a <strong>la</strong> realización <strong>de</strong> <strong>la</strong> práctica.<br />

Gracias a los alumnos que han contribuido a el<strong>la</strong>s, bien preguntando sobre<br />

algún problema que han encontrado, o incluso aportando directamente una solución<br />

correcta.<br />

Conversión <strong>de</strong> fechas:<br />

La conversión <strong>de</strong> fechas, tal y como vienen en el formato <strong>de</strong> los canales RSS<br />

<strong>de</strong> I<strong>de</strong>nti.ca, al formato <strong>de</strong> fechas datetime a<strong>de</strong>cuado para almacenar<strong>la</strong>s en<br />

una tab<strong>la</strong> <strong>de</strong> <strong>la</strong> base <strong>de</strong> datos se pue<strong>de</strong> hacer así:<br />

from email.utils import parsedate<br />

from datetime import datetime<br />

dbDate = datetime(*(parsedate(rssDate)[:6]))<br />

El uso <strong>de</strong> “*” permite, en este caso, obtener una referencia a <strong>la</strong> tup<strong>la</strong> <strong>de</strong> siete<br />

elementos que contiene los parámetros que espera datetime() (que son siete<br />

parámetros).<br />

Más información sobre parsedate() en <strong>la</strong> documentación <strong>de</strong>l módulo email.utils<br />

<strong>de</strong> Python.<br />

Envío <strong>de</strong> hojas CSS:<br />

Para que el navegador interprete a<strong>de</strong>cuadamente una hoja <strong>de</strong> estilo, pue<strong>de</strong><br />

ser conveniente fijar el tipo <strong>de</strong> contenidos <strong>de</strong> <strong>la</strong> respuesta HTTP en <strong>la</strong> que<br />

<strong>la</strong> aplicación <strong>la</strong> envía al navegador. En otras pa<strong>la</strong>bras, asegurar que cuando<br />

el navegador reciba <strong>la</strong> hoja CSS, le venga a<strong>de</strong>cuadamente marcada como <strong>de</strong><br />

tipo “text/css” (y no “text/html” o simi<strong>la</strong>r, que es como vendrá marcado<br />

normalmente lo que responda <strong>la</strong> aplicación).<br />

En código, bastaría con poner <strong>la</strong> cabecera “Content-Type” a<strong>de</strong>cuada al objeto<br />

que tiene <strong>la</strong> respuesta HTTP que <strong>de</strong>volverá <strong>la</strong> función que atien<strong>de</strong> a <strong>la</strong><br />

URL para servir <strong>la</strong> hoja CSS (normalmente, en views.py):<br />

myResponse = HttpResponse(cssText)<br />

myResponse[’Content-Type’] = ’text/css’<br />

return myResponse<br />

77


19.4. Práctica final (2011, junio)<br />

La entrega <strong>de</strong> esta práctica será necesaria para po<strong>de</strong>r optar a aprobar <strong>la</strong> <strong>asignatura</strong>.<br />

Este enunciado correspon<strong>de</strong> con <strong>la</strong> convocatoria <strong>de</strong> junio.<br />

La práctica final <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> consiste en <strong>la</strong> creación <strong>de</strong> una aplicación web<br />

<strong>de</strong> resumen y cache <strong>de</strong> micronotas (microblogs). En este enunciado, l<strong>la</strong>maremos a<br />

esa aplicación “MiResumen2”, y a los resúmenes <strong>de</strong> micronotas para cada usuario,<br />

“microresumen”.<br />

Los sitios <strong>de</strong> microblogs permiten a sus usuarios compartir notas breves (habitualmente<br />

<strong>de</strong> 140 caracteres o menos). Entre los más popu<strong>la</strong>res pue<strong>de</strong>n mencionarse<br />

Twitter 5 e I<strong>de</strong>nti.ca 6 . La aplicación web a realizar se encargará <strong>de</strong> mostrar <strong>la</strong>s<br />

micronotas que se indiquen, junto con información re<strong>la</strong>cionada. A continuación se<br />

<strong>de</strong>scribe el funcionamiento y arquitectura general <strong>de</strong> <strong>la</strong> aplicación, <strong>la</strong> funcionalidad<br />

mínima que <strong>de</strong>be proporcionar, y otra funcionalidad optativa que podrá tener.<br />

19.4.1. Arquitectura y funcionamiento general<br />

Arquitectura general:<br />

La práctica consistirá en una aplicación web que servirá los datos a los usuarios.<br />

La aplicación web se construirá como un proyecto Django, que incluirá una<br />

o varias aplicaciones Django que implementen <strong>la</strong> funcionalidad requerida.<br />

Para el almacenamiento <strong>de</strong> datos persistente se usará SQLite3, con tab<strong>la</strong>s<br />

<strong>de</strong>finidas según mo<strong>de</strong>los en Django.<br />

No se mantendrán usuarios con cuenta, ni usando <strong>la</strong> aplicación Django “Admin<br />

site” ni <strong>de</strong> otra manera. Por lo tanto, para usar el sitio no hará falta<br />

registrarse, ni entrar en una cuenta.<br />

Se utilizarán p<strong>la</strong>ntil<strong>la</strong>s Django (a ser posible, una jerarquía <strong>de</strong> p<strong>la</strong>ntil<strong>la</strong>s, para<br />

que toda <strong>la</strong> aplicación tenga un aspecto simi<strong>la</strong>r) para <strong>de</strong>finir <strong>la</strong>s páginas que<br />

se servirán a los navegadores <strong>de</strong> los usuarios. Estas p<strong>la</strong>ntil<strong>la</strong>s incluirán en<br />

todas <strong>la</strong>s páginas al menos:<br />

• Un banner (imagen) <strong>de</strong>l sitio, en <strong>la</strong> parte superior.<br />

• Un menú <strong>de</strong> opciones justo <strong>de</strong>bajo <strong>de</strong>l banner, formateado en una línea.<br />

• Un pie <strong>de</strong> página con una nota <strong>de</strong> copyright.<br />

5 http://twitter.com<br />

6 http://i<strong>de</strong>nti.ca<br />

78


Se utilizarán hojas <strong>de</strong> estilo CSS para <strong>de</strong>terminar <strong>la</strong> apariencia <strong>de</strong> <strong>la</strong> aplicación.<br />

Estas hojas se almacenará en <strong>la</strong> base <strong>de</strong> datos.<br />

Funcionamiento general:<br />

Se consi<strong>de</strong>rarán sólo micronotas en I<strong>de</strong>nti.ca. L<strong>la</strong>maremos a los usuarios <strong>de</strong><br />

I<strong>de</strong>nti.ca “micronoteros”.<br />

MiResumen2 recordará a todos sus visitantes. A estos efectos, consi<strong>de</strong>raremos<br />

como sesión <strong>de</strong> un visitante todas <strong>la</strong>s interacciones que se hagan con el sitio<br />

<strong>de</strong>s<strong>de</strong> el mismo navegador (por lo tanto, se podrán usar cookies <strong>de</strong> sesión<br />

para mantener esta re<strong>la</strong>ción).<br />

MiResumen2 mostrará notas <strong>de</strong> I<strong>de</strong>nti.ca, que se irán actualizando según se<br />

indica en el apartado siguiente.<br />

Los visitantes <strong>de</strong> MiResumen2 podrán seleccionar cualquier micronota que<br />

aparezca en él.<br />

Cada visitante podrá ver <strong>la</strong>s micronotas que ha seleccionado, por or<strong>de</strong>n inverso<br />

<strong>de</strong> publicación en I<strong>de</strong>nti.ca, en un listado que incluirá también <strong>la</strong> fecha<br />

en que seleccionó cada micronota.<br />

19.4.2. Funcionalidad mínima<br />

Para cada micronota en <strong>la</strong> base <strong>de</strong> datos <strong>de</strong>l p<strong>la</strong>neta, se mostrarán (salvo<br />

que se indique lo contrario):<br />

• el texto <strong>de</strong> <strong>la</strong> micronota<br />

• un en<strong>la</strong>ce a <strong>la</strong> micronota en I<strong>de</strong>nti.ca<br />

• el nombre <strong>de</strong>l micronotero que <strong>la</strong> puso (con un en<strong>la</strong>ce a su página en<br />

I<strong>de</strong>nti.ca)<br />

• <strong>la</strong> fecha en que se publicó en I<strong>de</strong>nti.ca<br />

• un botón para que cualquier visitante pueda seleccionar esta nota (o<br />

<strong>de</strong>seleccionar<strong>la</strong> si ya <strong>la</strong> había seleccionado)<br />

• si el usuario ha seleccionado <strong>la</strong> micronota, <strong>la</strong> fecha en que <strong>la</strong> había<br />

seleccionado<br />

• un número que representará el número <strong>de</strong> visitantes que han seleccionado<br />

esta micronota<br />

79


MiResumen2 mostrará en una interfaz pública (visible por cualquiera que<br />

visite el sitio) todas <strong>la</strong>s micronotas que tenga en <strong>la</strong> base <strong>de</strong> datos, organizadas<br />

en los siguientes recursos:<br />

• /: Microresumen <strong>de</strong> <strong>la</strong>s últimas 30 micronoticias almacenadas en MiResumen2,<br />

or<strong>de</strong>nadas por fecha inversa <strong>de</strong> publicación (más nuevos primero).<br />

A<strong>de</strong>más, incluirá un en<strong>la</strong>ce al recurso <strong>de</strong> actualización (ver más<br />

abajo), y al microresumen <strong>de</strong> <strong>la</strong>s 30 siguientes micronoticias (/30, ver<br />

más abajo)<br />

• /nnn: Microresumen <strong>de</strong> <strong>la</strong>s micronoticas entre <strong>la</strong> nnn y <strong>la</strong> nnn+29,<br />

según el or<strong>de</strong>n <strong>de</strong> fecha inversa <strong>de</strong> publicación (más nuevos primero,<br />

con números más bajos). Se consi<strong>de</strong>rará que <strong>la</strong> micronota más reciente<br />

es <strong>la</strong> micronota 0. Así, /0 mostrará lo mismo que / , /30 mostrará <strong>la</strong>s<br />

30 micronotas siguientes a <strong>la</strong>s mostradas en / y /40 mostrará <strong>la</strong>s micronotas<br />

<strong>de</strong> <strong>la</strong> 40 a <strong>la</strong> 67.<br />

• /update: Recurso <strong>de</strong> actualización: cuando se acceda a él, MiResumen2<br />

acce<strong>de</strong>rá al RSS <strong>de</strong> <strong>la</strong> página principal <strong>de</strong> I<strong>de</strong>nti.ca y extraerá <strong>de</strong> él<br />

<strong>la</strong>s últimas 20 micronotas (o menos, si no hay tantas micronotas en el<br />

canal que no estén ya en <strong>la</strong> base <strong>de</strong> datos), almacenándo<strong>la</strong>s en <strong>la</strong> base<br />

<strong>de</strong> datos y mostrándo<strong>la</strong>s.<br />

• /selected: Listado <strong>de</strong> todas <strong>la</strong>s micronotas seleccionadas por el visitante<br />

actual, or<strong>de</strong>nadas por fecha <strong>de</strong> publicación inversa (más nuevas primero).<br />

• /feed: Canal RSS con <strong>la</strong>s 10 micronotas más recientes (por fecha <strong>de</strong><br />

publicación) que ha seleccionado el visitante actual.<br />

• /conf: Configuración <strong>de</strong>l visitante. Incluirá campos para editar el nombre<br />

<strong>de</strong>l visitante, que se mostrará en todas <strong>la</strong>s páginas <strong>de</strong>l sitio que se<br />

sirvan a ese visitante.<br />

• /skin: Configuración <strong>de</strong>l estilo (skin) con el que el visitante quiere ver<br />

el sitio. Mediante un formu<strong>la</strong>rio, el visitante podrá editar el fichero CSS<br />

que codificará su estilo (y que se almacenará en <strong>la</strong> base <strong>de</strong> datos). Si<br />

no lo han cambiado, los visitantes tendrán el estilo CSS por <strong>de</strong>fecto <strong>de</strong>l<br />

sitio.<br />

• /cookies: Página HTML que incluirá un listado <strong>de</strong> <strong>la</strong>s cookies que se<br />

están usando con cada uno <strong>de</strong> los visitantes conocidos para <strong>la</strong> aplicación,<br />

en formato listo para que cada cookie pueda ser copiada y pegada en<br />

un editor <strong>de</strong> cookies.<br />

80


Para <strong>la</strong> generación <strong>de</strong> canales RSS y <strong>la</strong> gestión <strong>de</strong> sesiones y/o cookies se podrán<br />

usar los mecanismos que proporciona Django, o no, según el alumno consi<strong>de</strong>re que<br />

le sea más conveniente.<br />

19.4.3. Funcionalidad optativa<br />

De forma optativa, se podrá incluir cualquier funcionalidad relevante en el<br />

contexto <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>. Se valorarán especialmente <strong>la</strong>s funcionalida<strong>de</strong>s que impliquen<br />

el uso <strong>de</strong> técnicas nuevas, o <strong>de</strong> aspectos <strong>de</strong> Django no utilizados en los<br />

ejercicios previos, y que tengan sentido en el contexto <strong>de</strong> esta práctica y <strong>de</strong> <strong>la</strong><br />

<strong>asignatura</strong>.<br />

Sólo a modo <strong>de</strong> sugerencia, se incluyen algunas posibles funcionalida<strong>de</strong>s optativas:<br />

Uso <strong>de</strong> Ajax para algún aspecto <strong>de</strong> <strong>la</strong> práctica (por ejemplo, para seleccionar<br />

y <strong>de</strong>seleccionar una micronota).<br />

Votación <strong>de</strong> micronotas. Cada visitante podrá dar una puntuación entre 0 y<br />

10 a cada micronota. Cuando se muestre cada micronota en el sitio, a<strong>de</strong>más<br />

<strong>de</strong> los <strong>de</strong>más datos que se han mencionado, se incluirá <strong>la</strong> media <strong>de</strong> <strong>la</strong>s votaciones<br />

que ha tenido, y el número <strong>de</strong> votaciones que ha tenido esa micronota.<br />

Una vez que un visitante ha votado una micronota, no pue<strong>de</strong> volver a votar<strong>la</strong>,<br />

ni cambiar su votación.<br />

Soporte para avatares. Cada micronota se presentará junto con el avatar<br />

(imagen) correspondiente al micronotero que <strong>la</strong> ha puesto.<br />

Soporte para Twitter y/o otros sitios <strong>de</strong> microblogging (micronotas) a<strong>de</strong>más<br />

<strong>de</strong> I<strong>de</strong>nti.ca<br />

En<strong>la</strong>ce a URLs, etiquetas y micronoteros referenciados. Se i<strong>de</strong>ntificarán en<br />

<strong>la</strong>s micronotas los textos que tengan formato <strong>de</strong> URL, y se mostrará esa URL<br />

como en<strong>la</strong>ce, los que tengan formato <strong>de</strong> etiqueta (tag, nombres que comienzan<br />

por #), mostrándolos como en<strong>la</strong>ce a <strong>la</strong> página I<strong>de</strong>nti.ca para ese tag, y los<br />

micronoteros referenciados (nombres que comienzan por @), mostrándolos<br />

como en<strong>la</strong>ce a <strong>la</strong> página <strong>de</strong>l micronotero en cuestión en I<strong>de</strong>nti.ca.<br />

Recomendación <strong>de</strong> micronotas. En una página, se mostrarán <strong>la</strong>s micronotas<br />

que probablemente interesen al micronotero, basada en <strong>la</strong> historia <strong>de</strong> elecciones<br />

pasadas. El algoritmo a usarse pue<strong>de</strong> ser: busca los tres visitantes que<br />

más notas hayan elegido en común con <strong>la</strong>s <strong>de</strong>l visitante actual, y muestra<br />

todas <strong>la</strong>s micronotas que hayan elegido esos visitantes y el visitante actual<br />

aún no ha elegido.<br />

81


19.4.4. Entrega <strong>de</strong> <strong>la</strong> práctica<br />

La práctica se entregará electrónicamente como muy tar<strong>de</strong> el día 17 <strong>de</strong> junio a<br />

<strong>la</strong>s 23:00.<br />

A<strong>de</strong>más, los alumnos que hayan presentado <strong>la</strong>s prácticas podrán tener que<br />

realizar una entrega presencial el día que esté fijado el examen <strong>de</strong> teoría <strong>de</strong> <strong>la</strong><br />

<strong>asignatura</strong>. La entrega presencial se realizará en el <strong>la</strong>boratorio don<strong>de</strong> tienen lugar<br />

habitualmente <strong>la</strong>s c<strong>la</strong>ses <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Cada alumno entregará su práctica colocándo<strong>la</strong> en un directorio en su cuenta<br />

en el <strong>la</strong>boratorio. El directorio, que <strong>de</strong>berá colgar directamente <strong>de</strong> su directorio<br />

hogar ($HOME), se l<strong>la</strong>mará “pf django 2010 2”.<br />

El directorio que se entregue <strong>de</strong>berá constar <strong>de</strong> un proyecto Django completo y<br />

listo para funcionar en el entorno <strong>de</strong>l <strong>la</strong>boratorio, incluyendo <strong>la</strong> base <strong>de</strong> datos con<br />

datos suficientes como para po<strong>de</strong>r probarlo. Estos datos incluirán al menos cinco<br />

visitantes diferentes, cada uno con al menos 3 micronotas elegidas, y un total <strong>de</strong><br />

al menos 50 micronotas en <strong>la</strong> base <strong>de</strong> datos <strong>de</strong> MiResumen2<br />

Se incluirá también en el directorio que se entregue un fichero README con<br />

los siguientes datos:<br />

Nombre <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

Nombre completo <strong>de</strong>l alumno.<br />

Nombre <strong>de</strong> su cuenta en el <strong>la</strong>boratorio.<br />

Resumen <strong>de</strong> <strong>la</strong>s peculiarida<strong>de</strong>s que se quieran mencionar sobre lo implementado<br />

en <strong>la</strong> parte obligatoria.<br />

Lista <strong>de</strong> funcionalida<strong>de</strong>s opcionales que se hayan implementado, y breve<br />

<strong>de</strong>scripción <strong>de</strong> cada una.<br />

Es importante que estas normas se cump<strong>la</strong>n estrictamente, y <strong>de</strong> forma especial<br />

<strong>la</strong>s que se refieren al nombre <strong>de</strong>l directorio, porque <strong>la</strong> recogida <strong>de</strong> <strong>la</strong>s prácticas, y<br />

parcialmente su prueba, se hará con herramientas automáticas.<br />

[Las normas <strong>de</strong> entrega podrán incluir más <strong>de</strong>talles en el futuro, compruéba<strong>la</strong>s<br />

antes <strong>de</strong> realizar <strong>la</strong> entrega.]<br />

19.4.5. Notas y comentarios<br />

La práctica <strong>de</strong>berá funcionar en el entorno GNU/Linux (Ubuntu) <strong>de</strong>l <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, con <strong>la</strong> versión 1.2.3 <strong>de</strong> Django.<br />

La práctica <strong>de</strong>berá funcionar <strong>de</strong>s<strong>de</strong> el navegador Firefox disponible en el <strong>la</strong>boratorio<br />

<strong>de</strong> <strong>la</strong> <strong>asignatura</strong>.<br />

82


Se recomienda construir una o varias aplicaciones complementarias para probar<br />

<strong>la</strong> <strong>de</strong>scarga y almacenamiento en base <strong>de</strong> datos <strong>de</strong>l canal que alimentarán<br />

MiResumen.<br />

Los canales (feeds) RSS que produce <strong>la</strong> aplicación web realizada en <strong>la</strong> práctica<br />

<strong>de</strong>berán funcionar al menos con el agregador Liferea y el que lleva integrado<br />

Firefox.<br />

Se recomienda utilizar alguna extensión para Firefox que permita manipu<strong>la</strong>r<br />

cookies para po<strong>de</strong>r probar <strong>la</strong> aplicación simu<strong>la</strong>ndo varios visitantes <strong>de</strong>s<strong>de</strong> el mismo<br />

navegador.<br />

19.4.6. Notas <strong>de</strong> ayuda<br />

A continuación, algunas notas que podrían ayudar a <strong>la</strong> realización <strong>de</strong> <strong>la</strong> práctica.<br />

Gracias a los alumnos que han contribuido a el<strong>la</strong>s, bien preguntando sobre<br />

algún problema que han encontrado, o incluso aportando directamente una solución<br />

correcta.<br />

Conversión <strong>de</strong> fechas:<br />

La conversión <strong>de</strong> fechas, tal y como vienen en el formato <strong>de</strong> los canales RSS<br />

<strong>de</strong> I<strong>de</strong>nti.ca, al formato <strong>de</strong> fechas datetime a<strong>de</strong>cuado para almacenar<strong>la</strong>s en<br />

una tab<strong>la</strong> <strong>de</strong> <strong>la</strong> base <strong>de</strong> datos se pue<strong>de</strong> hacer así:<br />

from email.utils import parsedate<br />

from datetime import datetime<br />

dbDate = datetime(*(parsedate(rssDate)[:6]))<br />

El uso <strong>de</strong> “*” permite, en este caso, obtener una referencia a <strong>la</strong> tup<strong>la</strong> <strong>de</strong> siete<br />

elementos que contiene los parámetros que espera datetime() (que son siete<br />

parámetros).<br />

Más información sobre parsedate() en <strong>la</strong> documentación <strong>de</strong>l módulo email.utils<br />

<strong>de</strong> Python.<br />

Envío <strong>de</strong> hojas CSS:<br />

Para que el navegador interprete a<strong>de</strong>cuadamente una hoja <strong>de</strong> estilo, pue<strong>de</strong><br />

ser conveniente fijar el tipo <strong>de</strong> contenidos <strong>de</strong> <strong>la</strong> respuesta HTTP en <strong>la</strong> que<br />

<strong>la</strong> aplicación <strong>la</strong> envía al navegador. En otras pa<strong>la</strong>bras, asegurar que cuando<br />

el navegador reciba <strong>la</strong> hoja CSS, le venga a<strong>de</strong>cuadamente marcada como <strong>de</strong><br />

tipo “text/css” (y no “text/html” o simi<strong>la</strong>r, que es como vendrá marcado<br />

normalmente lo que responda <strong>la</strong> aplicación).<br />

83


En código, bastaría con poner <strong>la</strong> cabecera “Content-Type” a<strong>de</strong>cuada al objeto<br />

que tiene <strong>la</strong> respuesta HTTP que <strong>de</strong>volverá <strong>la</strong> función que atien<strong>de</strong> a <strong>la</strong><br />

URL para servir <strong>la</strong> hoja CSS (normalmente, en views.py):<br />

myResponse = HttpResponse(cssText)<br />

myResponse[’Content-Type’] = ’text/css’<br />

return myResponse<br />

84


20. Examenes pasados <strong>de</strong> <strong>la</strong> <strong>asignatura</strong> Servicios<br />

y Aplicaciones Telemáticas<br />

Nota importante: cada año, <strong>la</strong> <strong>asignatura</strong> tenía un temario y un enfoque diferentes,<br />

y por tanto también se incluían diferentes áreas temáticas en el exámen<br />

que no necesariamente se incluirían hoy.<br />

20.1. 2 <strong>de</strong> febrero <strong>de</strong> 2007<br />

Después <strong>de</strong> llevar un tiempo buscando trabajo, y no encontrar dón<strong>de</strong> valoren sus<br />

habilida<strong>de</strong>s, un amigo te propone que le ayu<strong>de</strong>s a encontrarlo por <strong>la</strong> vía <strong>de</strong> construir<br />

un sitio web don<strong>de</strong> quien quiera pueda poner su currículum. En particu<strong>la</strong>r, se<br />

preten<strong>de</strong> que:<br />

Cualquiera pueda subir información estructurada sobre él mismo (su currículum)<br />

rellenando un formu<strong>la</strong>rio. También podrá subir su foto, y un documento<br />

HTML con el contenido que quiera (por ejemplo, su currículum en formato<br />

libre).<br />

Uno <strong>de</strong> los campos obligatorios <strong>de</strong>l formu<strong>la</strong>rio para subir el currículum estructurado<br />

sea una dirección <strong>de</strong> correo.<br />

La información que se haya subido sólo se publique cuando haya sido validada,<br />

usando para ello <strong>la</strong> cuenta <strong>de</strong> correo electrónico.<br />

Toda <strong>la</strong> información que se suba sea pública, en una página HTML para<br />

cada currículum. Esa página tendrá, en formato HTML, el contenido <strong>de</strong>l<br />

currículum estructurado. En el<strong>la</strong> se verá también <strong>la</strong> foto, y un en<strong>la</strong>ce al<br />

documento HTML opcional (que estará en página aparte).<br />

No haya cuentas <strong>de</strong> usuario.<br />

Quien haya subido información pueda modificar<strong>la</strong> (o eliminar<strong>la</strong>), si lo hace<br />

<strong>de</strong>s<strong>de</strong> el mismo navegador.<br />

Aprovechando que hay que hacer un examen <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, se te pi<strong>de</strong> que,<br />

para el sistema <strong>de</strong>scrito, <strong>de</strong>talles los siguientes aspectos:<br />

1. Dibuja, y comenta brevemente, el esquema <strong>de</strong>l sistema: programas implicados,<br />

protocolos utilizados (indicando entre qué programas se usarán), etc.<br />

Indica también un esquema <strong>de</strong> urls que se pueda usar para <strong>la</strong> consulta <strong>de</strong><br />

los currícu<strong>la</strong> estructurados, <strong>la</strong>s fotos, y los documentos anexos que se hayan<br />

subido.<br />

85


2. Describe todas <strong>la</strong>s interacciones HTTP necesarias para ver en el navegador <strong>la</strong><br />

página principal <strong>de</strong> un currículum, suponiendo que se conoce su url. Indica <strong>la</strong>s<br />

principales cabeceras, y el contenido <strong>de</strong>l cuerpo <strong>de</strong> cada solicitud y respuesta<br />

HTTP.<br />

3. Describe todas <strong>la</strong>s interacciones HTTP necesarias para subir un nuevo currículum<br />

(también con cabeceras y cuerpo).<br />

4. Describe todas <strong>la</strong>s interacciones HTTP necesarias para borrar un currículum.<br />

5. Sin pedir ningún dato nuevo al usuario, diseña un mecanismo que permita<br />

modificar un currículum a quien lo subió, haciéndolo <strong>de</strong>s<strong>de</strong> un or<strong>de</strong>nador<br />

distinto al que usó en aquel momento.<br />

6. ¿En qué podría ser útil usar SSL en este sistema (sin ampliar <strong>la</strong> funcionalidad<br />

<strong>de</strong>scrita).<br />

7. ¿En qué podría ser útil WebDAV en este sistema<br />

8. Describe el esquema general <strong>de</strong> un canal RSS que publicase información sobre<br />

los 10 últimos currícu<strong>la</strong> subidos (para cada uno, nombre y url <strong>de</strong>l currículum<br />

estructurado).<br />

20.2. 4 <strong>de</strong> septiembre <strong>de</strong> 2007<br />

Harta/o <strong>de</strong> ligar en el metro, y aplicando tus conocimientos en esta <strong>asignatura</strong>,<br />

<strong>de</strong>ci<strong>de</strong>s construir un sitio web para buscar pareja. Su requisitos son los siguientes:<br />

Cualquiera pueda subir información estructurada con sus propios datos personales<br />

(los datos que utilizará el sistema para proponer parejas) rellenando<br />

un formu<strong>la</strong>rio. También podrá subir su foto, y un ví<strong>de</strong>o en formato MPEG<br />

con una presentación.<br />

Uno <strong>de</strong> los campos obligatorios <strong>de</strong>l formu<strong>la</strong>rio para subir los datos personales<br />

será una dirección <strong>de</strong> correo.<br />

La información que se haya subido sólo se consi<strong>de</strong>rará en el sistema, y se<br />

ofrecerá a otros usuarios, cuando haya sido validada, usando para ello <strong>la</strong><br />

cuenta <strong>de</strong> correo electrónico.<br />

Toda <strong>la</strong> información que se suba estará accesible sólo a otros usuarios que<br />

hayan subido su propia información personal, y ésta haya sido validada.<br />

86


Para usuario, su información se ofrecerá en una página, en formato HTML.<br />

En el<strong>la</strong> se verá también <strong>la</strong> foto, y un en<strong>la</strong>ce a <strong>la</strong> pelícu<strong>la</strong> <strong>de</strong> presentación (que<br />

en caso <strong>de</strong> pincharlo, se <strong>de</strong>scargará).<br />

Como parte <strong>de</strong> sus datos personales, cada usuario elegirá un nombre <strong>de</strong><br />

usuario y una contraseña, que utilizará cada vez que quiera modificar los<br />

datos o consultar los <strong>de</strong> otros usuarios.<br />

Para organizar tus i<strong>de</strong>as, y antes <strong>de</strong> ponerte a programar, has <strong>de</strong> poner por<br />

escrito algunos aspectos importantes <strong>de</strong>l sistema:<br />

1. Dibuja, y comenta brevemente, el esquema <strong>de</strong>l sistema: programas implicados,<br />

protocolos utilizados (indicando entre qué programas se usarán), etc.<br />

Indica también un esquema <strong>de</strong> urls que se pueda usar para <strong>la</strong> consulta <strong>de</strong> <strong>la</strong><br />

información personal, <strong>la</strong>s fotos, y los ví<strong>de</strong>os que se hayan subido.<br />

2. Describe todas <strong>la</strong>s interacciones HTTP necesarias para ver en el navegador<br />

<strong>la</strong> página con los datos personales <strong>de</strong> un usuario, suponiendo que se está ya<br />

autenticado como usuario <strong>de</strong>l sistema, y que se conoce ya su url. Indica <strong>la</strong>s<br />

principales cabeceras, y el contenido <strong>de</strong>l cuerpo <strong>de</strong> cada solicitud y respuesta<br />

HTTP.<br />

3. Describe todas <strong>la</strong>s interacciones HTTP necesarias para subir los datos <strong>de</strong> un<br />

usuario nuevo (incluyendo foto, pero no ví<strong>de</strong>o). (también con cabeceras y<br />

cuerpo).<br />

4. Describe todas <strong>la</strong>s interacciones HTTP necesarias para que un usuario pueda<br />

borrar un ví<strong>de</strong>o que ha subido.<br />

5. Describe el procedimiento <strong>de</strong> autenticación para un usuario, <strong>de</strong>s<strong>de</strong> que pi<strong>de</strong><br />

<strong>la</strong> primera página <strong>de</strong>l sitio, hasta que éste le permite <strong>de</strong>scargar cualquier<br />

página con información <strong>de</strong> otro usuario.<br />

6. ¿En qué podría ser útil usar SSL en este sistema (sin ampliar <strong>la</strong> funcionalidad<br />

<strong>de</strong>scrita).<br />

7. ¿En qué podría ser útil WebDAV en este sistema<br />

8. Describe el esquema general <strong>de</strong> un canal RSS que publicase información<br />

sobre los 10 usuarios que más se ajusten al perfil (según los datos personales<br />

proporcionados) <strong>de</strong> un usuario, incluyendo al menos su nombre y <strong>la</strong> url <strong>de</strong><br />

los datos personales <strong>de</strong> cada uno.<br />

87


20.3. 12 <strong>de</strong> febrero <strong>de</strong> 2008<br />

Unos amigos, que opinan que piedra-papel-tijera es el mejor juego que ha inventado<br />

<strong>la</strong> humanidad, quieren po<strong>de</strong>r jugarlo mediante Internet, ya que no siempre<br />

pue<strong>de</strong>n quedar para ello. Después <strong>de</strong> pensarlo un poco, <strong>de</strong>ci<strong>de</strong>n que el juego se<br />

implemente como un servicio web, según el siguiente <strong>de</strong>talle:<br />

Usarán un servidor web accesible mediante <strong>la</strong> url http://ppt.info<br />

Para cada partida, se <strong>de</strong>finirá un número <strong>de</strong> 15 dígitos. Todas <strong>la</strong>s urls <strong>de</strong><br />

cada partida comentarán por http://ppt.info/numero/ (siendo “numero” el<br />

número <strong>de</strong>finido para esa partida)<br />

Para jugar, cada jugador invocará una operación GET <strong>de</strong> HTTP sobre <strong>la</strong> url<br />

“piedra”, “papel” o “tijera” (por ejemplo, http://ppt.info/numero/papel )<br />

Para cada partida, el servidor consi<strong>de</strong>rará <strong>la</strong>s dos primeras operaciones “GET”<br />

que lleguen. Ganará el jugador que haya invocado <strong>la</strong> ganadora, según <strong>la</strong>s reg<strong>la</strong>s<br />

<strong>de</strong>l juego (piedra gana a tijera, papel gana a piedra, tijera gana a papel,<br />

empate en caso <strong>de</strong> que los dos jugadores elijan lo mismo)<br />

Si se invoca un GET para jugar, indicando una url con número <strong>de</strong> partida<br />

bien formado y opción válida (piedra, papel o tijera), y no se ha recibido<br />

otro antes para esa partida, el servidor respon<strong>de</strong>rá con<br />

“Comienza partida número numero. Este jugador ha elegido opcion. Quedo<br />

esperando al segundo jugador”<br />

sustituyendo opcion por <strong>la</strong> opción <strong>de</strong> juego que haya elegido el jugador (piedra,<br />

papel o tijera), y numero por el número <strong>de</strong> partida.<br />

Si se invoca un GET para jugar, indicando una url con número <strong>de</strong> partida<br />

bien formado y opción válida (piedra, papel o tijera), y ya se ha recibido otro<br />

válido antes para esa partida, el servidor respon<strong>de</strong>rá con<br />

“Juego terminado. El primer jugador eligió opcion1. El segundo jugador eligió<br />

opcion2. Gana opcion ganadora.”<br />

sustituyendo opcion1 por <strong>la</strong> que eligió el primer jugador, opcion2 por <strong>la</strong><br />

que ha elegido este segundo jugador, y opcion ganadora <strong>la</strong> que gane, <strong>de</strong><br />

acuerdo con <strong>la</strong>s reg<strong>la</strong>s <strong>de</strong>l juego. Si hay empate, en lugar <strong>de</strong> <strong>la</strong> última frase<br />

pondrá “Empate”.<br />

Si se invoca un GET para jugar, y ya se han recibido dos válidos antes para<br />

esa partida, el servidor respon<strong>de</strong>rá con lo mismo que respondió al segundo<br />

jugador.<br />

88


Si se invoca un GET con número <strong>de</strong> partida bien formado y en lugar <strong>de</strong> <strong>la</strong><br />

opción <strong>la</strong> ca<strong>de</strong>na “estado” (por ejemplo, http://ppt.info/numero/estado ),<br />

el servidor respon<strong>de</strong>rá<br />

“Partida no iniciada”<br />

si no se ha recibido aún ninguna petición válida para jugar. Si se ha recibido<br />

una, respon<strong>de</strong>rá con el mensaje que vio el primer jugador. Si se han recibido<br />

dos o más, con el mensaje que vio el segundo jugador.<br />

Si se invoca un GET inválido (número <strong>de</strong> juego mal formado o opción <strong>de</strong><br />

juego inválida), respon<strong>de</strong>rá con código <strong>de</strong> error y mensaje “Recurso no disponible”<br />

Si el servidor <strong>de</strong>l juego cae, se entien<strong>de</strong> que se pier<strong>de</strong>n todas <strong>la</strong>s partidas que<br />

estuvieran en curso o ya se hayan terminado. Al volver a inicializarse, todas<br />

<strong>la</strong>s partidas estarán por empezar.<br />

Aprovechando que hay que hacer un examen <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, se te pi<strong>de</strong> que,<br />

para el sistema <strong>de</strong>scrito, <strong>de</strong>talles los siguientes aspectos:<br />

1. Dibuja, y comenta brevemente, el esquema <strong>de</strong>l sistema: programas implicados,<br />

protocolos utilizados (indicando entre qué programas se usarán), etc.<br />

Trata <strong>de</strong> hacer el diseño con el mínimo número posible <strong>de</strong> programas, y<br />

justifica c<strong>la</strong>ramente <strong>la</strong> necesidad <strong>de</strong> cada uno que introduzcas. Según ese<br />

esquema, <strong>de</strong>scribe todas <strong>la</strong>s interacciones HTTP necesarias para jugar una<br />

partida contra uno mismo, jugando “piedra” y “papel”.<br />

2. Se supone que los navegadores con los que se quiere jugar implementan cookies<br />

como está <strong>de</strong>finido en el estándar correspondiente. ¿Podrían en ese caso<br />

usarse cookies para asegurarse <strong>de</strong> que en una partida los dos jugadores juegan<br />

<strong>de</strong>s<strong>de</strong> diferentes navegadores Si <strong>la</strong> respuesta es positiva, indica cómo<br />

irían <strong>la</strong>s cookies en cada interacción HTTP, y cuándo se generarían. Si <strong>la</strong><br />

respuesta es negativa, indica por qué <strong>la</strong>s cookies no sirven en este caso.<br />

3. Sin pedir ningún dato nuevo a los jugadores, queremos tener una c<strong>la</strong>sificación<br />

con los mejores jugadores (los que han ganado más veces). Para ello,<br />

usaremos <strong>la</strong> url http://ppt.info/top, don<strong>de</strong> aparecerá un i<strong>de</strong>ntificador para<br />

cada jugador, junto con <strong>la</strong>s veces que ha ganado. ¿Cómo implementarías esta<br />

funcionalidad con cookies<br />

4. Se quiere que el sistema mantenga <strong>la</strong> información, tanto <strong>de</strong> <strong>la</strong>s partidas en<br />

curso, como <strong>de</strong> <strong>la</strong>s ya jugadas, como <strong>de</strong> otra información (por ejemplo, <strong>la</strong><br />

c<strong>la</strong>sificación <strong>de</strong>scrita en el apartado anterior), incluso en el caso <strong>de</strong> caídas <strong>de</strong>l<br />

89


servidor. Describe qué modificaciones habría que hacer al diseño <strong>de</strong>l apartado<br />

1 para conseguirlo.<br />

5. Se quiere servir <strong>la</strong> c<strong>la</strong>sificación <strong>de</strong> los mejores jugadores mediante un canal<br />

XML. Escribe cómo podría ser el contenido <strong>de</strong> ese canal. Propón también<br />

una alternativa a usar XML indicando sus ventajas e inconvenientes.<br />

6. ¿Se podría construir un gadget, para integrar en un mashup, que permitiese<br />

jugar a este juego Si <strong>la</strong> respuesta es positiva, ¿cómo Si es negativa, ¿por<br />

qué<br />

20.4. 5 <strong>de</strong> septiembre <strong>de</strong> 2008<br />

Cada vez son más popu<strong>la</strong>res los dispositivos GPS que permiten almacenar el<br />

listado <strong>de</strong> puntos geográficos por los que se ha pasado, componiendo rutas. También<br />

se está haciendo cada vez más común el uso <strong>de</strong> dispositivos móviles (teléfonos<br />

móviles, por ejemplo) permanentemente conectados a Internet mediante GPRS,<br />

UMTS o simi<strong>la</strong>r que pue<strong>de</strong>n enviar <strong>de</strong> forma periódica mensajes con <strong>la</strong> posición<br />

<strong>de</strong>l dispositivo a don<strong>de</strong> quiera el usuario. Sin embargo, muchos usuarios no están<br />

interesados en dar a conocer <strong>de</strong> forma pública su localización, sino sólo permitir <strong>de</strong><br />

forma limitada que ciertas personas conozcan ciertos <strong>de</strong>talles sobre dón<strong>de</strong> estamos.<br />

En este contexto, una empresa <strong>de</strong>ci<strong>de</strong> montar un sitio web que permita compartir<br />

recorridos pasados, y recibir alertas que indique cuándo ha habido una cierta<br />

proximidad entre usuarios (siempre sujeto a que éstos hayan dado permiso para<br />

compartir sus coor<strong>de</strong>nadas). El sitio funciona <strong>de</strong> <strong>la</strong> siguiente forma:<br />

1. El sitio recibe cada minuto mensajes <strong>de</strong> los dispositivos <strong>de</strong> sus usuarios,<br />

indicando <strong>la</strong>s posiciones geográficas en <strong>la</strong>s que están.<br />

2. Estas posiciones son almacenadas en una base <strong>de</strong> datos.<br />

3. Los usuarios pue<strong>de</strong>n <strong>de</strong>cidir que <strong>la</strong> información sobre su posición pueda ser<br />

usada para informar <strong>de</strong> proximidad, <strong>de</strong> forma restringida, a ciertos otros<br />

usuarios. L<strong>la</strong>maremos a estos “usuarios con permiso”, para acce<strong>de</strong>r a información<br />

<strong>de</strong> proximidad <strong>de</strong> un usuario dado. Si un usuario no tiene permiso<br />

para acce<strong>de</strong>r a información sobre proximidad <strong>de</strong> otro usuario, el sistema no<br />

lo tendrá en cuenta cuando genere ese tipo <strong>de</strong> información.<br />

4. En cualquier momento, cada usuario pue<strong>de</strong> consultar en el sitio una página<br />

en <strong>la</strong> que pue<strong>de</strong> ver alertas <strong>de</strong> proximidad <strong>de</strong> otros usuarios que le han dado<br />

permiso para ello. Esta información estará en una página en formato HTML,<br />

indicando los nombres <strong>de</strong> esos usuarios, y <strong>la</strong> distancia a <strong>la</strong> que están (si ésta<br />

es menor <strong>de</strong> 10 km.)<br />

90


5. A<strong>de</strong>más, <strong>de</strong>s<strong>de</strong> esa página HTML se en<strong>la</strong>za a una página XML con <strong>la</strong> misma<br />

información en formato XML, y a un documento PDF imprimible, también<br />

con <strong>la</strong> misma información.<br />

6. Cada usuario podrá acce<strong>de</strong>r también a una página XML para cada nombre<br />

<strong>de</strong> usuario <strong>de</strong>l sitio. Esta página contendrá información sobre <strong>la</strong> distancia a<br />

<strong>la</strong> que está el usuario en cuestión (si le ha dado permiso), o una indicación<br />

<strong>de</strong> que no tiene permiso (si no se lo ha dado).<br />

7. Hay un sistema <strong>de</strong> creación <strong>de</strong> cuentas y autenticación ya diseñado, y que se<br />

supone que está fuera <strong>de</strong> lo que se pi<strong>de</strong> en este ejercicio. Basta con saber que<br />

una vez que un usuario que tiene cuenta se autentica, su navegador recibe una<br />

cookie <strong>de</strong> sesión, y que cuando el usuario “sale” <strong>de</strong> su cuenta, su navegador<br />

recibe una cookie <strong>de</strong> sesión nu<strong>la</strong> (por ejemplo, un cero).<br />

8. El sitio pue<strong>de</strong> ser visitado por usuarios que no tienen cuenta (anónimos),<br />

aunque éstos sólo podrán ver <strong>la</strong> información genérica <strong>de</strong> <strong>la</strong> página principal,<br />

que indicará el número <strong>de</strong> usuarios registrados, y cuántos usuarios registrados<br />

tienen al menos otro usuario en su proximidad.<br />

En particu<strong>la</strong>r, y teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Describe el sistema que diseñes para ofrecer el servicio. Supóngase que todo<br />

se hace en una so<strong>la</strong> máquina. Indíquese qué aplicaciones serán necesarias,<br />

qué protocolos usarán estas aplicaciones para interactuar entre el<strong>la</strong>s, y cómo<br />

encajará el navegador <strong>de</strong> los usuarios en este esquema.<br />

2. Propón un diseño REST <strong>de</strong>l servicio (sólo <strong>de</strong> <strong>la</strong> parte que se ofrece a usuarios).<br />

Especifica URLs y métodos HTTP utilizados, indicando <strong>la</strong> semántica<br />

<strong>de</strong> cada uno <strong>de</strong> estos (esto es, qué ocurrirá cuando se invoque cada método<br />

sobre cada URL).<br />

3. Para actualizar su posición, los dispositivos <strong>de</strong> los usuarios tendrán que enviar<br />

información al servicio. Esta información estará compuesta por unas<br />

coor<strong>de</strong>nadas <strong>de</strong> <strong>la</strong>titud y longitud (grados, minutos y segundos, para cada<br />

una <strong>de</strong> el<strong>la</strong>s), el usuario al que correspon<strong>de</strong>n, y una c<strong>la</strong>ve que se proporcionará<br />

al registrarse. Describe un posible formato para el cuerpo <strong>de</strong> una<br />

petición HTTP don<strong>de</strong> se envíe esta información. Se pi<strong>de</strong> que vaya codificada<br />

bien como x-form-urlenco<strong>de</strong>d, como XML (siguiendo algún estándar o un<br />

vocabu<strong>la</strong>rio a medida), o como JSON.<br />

4. Describe todas <strong>la</strong>s interacciones que tendrán lugar en el sistema (en todos<br />

los protocolos implicados, según el diseño que has propuesto en el apartado<br />

91


correspondiente) para que un usuario ya autenticado vea los usuarios que le<br />

han dado permiso que están cercanos a él.<br />

5. Describe todas <strong>la</strong>s interacciones que tendrán lugar en el sistema (en todos<br />

los protocolos implicados, según el diseño que has propuesto en el apartado<br />

correspondiente) para que un usuario ya autenticado vea <strong>la</strong> distancia a <strong>la</strong><br />

que está un cierto usuario que le ha dado permiso.<br />

6. Describe <strong>la</strong> misma situación, pero para un usuario que no le ha dado permiso.<br />

7. Escribe cómo podría ser <strong>la</strong> página XML con <strong>la</strong> información sobre <strong>la</strong> cercanía<br />

<strong>de</strong> un usuario concreto (<strong>la</strong> que se menciona en <strong>la</strong> <strong>de</strong>scripción <strong>de</strong>l servicio).<br />

Todos los apartados supondrán <strong>la</strong> misma puntuación en caso <strong>de</strong> ser respondidos<br />

correctamente.<br />

20.5. 18 <strong>de</strong> enero <strong>de</strong> 2010<br />

Se quiere construir un sitio web (mediante una aplicación web) <strong>de</strong> registro<br />

<strong>de</strong> recursos en Internet. Cada recurso es accesible mediante una url (<strong>la</strong> url don<strong>de</strong><br />

resi<strong>de</strong> ese recurso, en cualquier lugar <strong>de</strong> Internet). El sistema mantendrá para cada<br />

recurso una ficha con información sobre él.<br />

Cada ficha incluye <strong>la</strong> siguiente información sobre un recurso:<br />

1. Url don<strong>de</strong> está disponible el recurso<br />

2. Nombre <strong>de</strong>l recurso<br />

3. Descripción <strong>de</strong>l recurso (unas cuantas líneas <strong>de</strong> texto libre)<br />

4. Si el recurso es una página HTML, contenido <strong>de</strong> <strong>la</strong> página.<br />

5. Si el recurso es un canal RSS, contenido <strong>de</strong>l canal.<br />

6. Si el recurso es un fichero CSS, texto <strong>de</strong>l fichero CSS.<br />

7. Puntuaciones que se hayan podido dar a ese recurso. Las puntuaciones serán<br />

un valor entre 0 y 6, y cada recurso pue<strong>de</strong> tener muchas puntuaciones asociadas.<br />

8. Puntuación media <strong>de</strong>l recurso. Media aritmética <strong>de</strong> <strong>la</strong>s puntuaciones que se<br />

hayan dado al recurso.<br />

92


Para discriminar qué tipo <strong>de</strong> recurso es, se analizará el campo correspondiente<br />

<strong>de</strong> <strong>la</strong>s cabeceras HTTP que se reciben al solicitar el recurso.<br />

El sistema funcionará según se indica a continuación:<br />

1. Cualquier visitante <strong>de</strong>l sitio web podrá ver <strong>la</strong>s fichas <strong>de</strong> todos los recursos<br />

registrados.<br />

2. Cualquier visitante <strong>de</strong>l sitio web podrá dar <strong>de</strong> alta <strong>la</strong> ficha <strong>de</strong> un nuevo recurso.<br />

Si al tratar <strong>de</strong> dar<strong>la</strong> <strong>de</strong> alta, se comprueba que el recurso ya está registrado,<br />

se impedirá el nuevo registro. Al dar <strong>de</strong> alta un recurso, le asignará un<br />

nombre y una <strong>de</strong>scripción.<br />

3. Cualquier visitante <strong>de</strong>l sitio podrá editar <strong>la</strong> <strong>de</strong>scripción o el nombre <strong>de</strong>l<br />

recurso, cambiándolos por otros nuevos.<br />

4. Cualquier visitante <strong>de</strong>l sitio podrá ver <strong>la</strong> lista histórica <strong>de</strong> <strong>de</strong>scripciones y<br />

nombres que ha tenido cualquier recurso (si es que ha tenido más <strong>de</strong> una).<br />

5. Cualquier visitante <strong>de</strong>l sitio que haya registrado un recurso podrá puntuar<br />

cualquier otro recurso (pero no el que subió).<br />

6. Cuando un visitante sube información al sitio por primera vez (pue<strong>de</strong> ser<br />

un registro <strong>de</strong> recurso, o una edición <strong>de</strong> nombre o <strong>de</strong>scripción <strong>de</strong> recurso), el<br />

sistema le pedirá un nombre. Este nombre no podrá ser igual a otro usado<br />

previamente por cualquier otro visitante. Cuando el visitante vuelva a subir<br />

información <strong>de</strong>s<strong>de</strong> el mismo navegador, el sistema ya no le pedirá el nombre,<br />

y <strong>la</strong> subirá bajo el mismo nombre.<br />

7. La fichas, los nombres, <strong>de</strong>scripciones y puntuaciones <strong>de</strong> recurso se verán<br />

siempre anotadas con el nombre <strong>de</strong>l visitante que los creó o editó.<br />

8. En una cierta página será posible ver todos los recursos registrados. Para cada<br />

recurso se verá su url, un en<strong>la</strong>ce a su ficha, y su media <strong>de</strong> puntuaciones. Los<br />

recursos estarán or<strong>de</strong>nados por fecha <strong>de</strong> última modificación (<strong>de</strong> su nombre<br />

o <strong>de</strong> su <strong>de</strong>scripción).<br />

9. En otra página será posible ver todos los recursos registrados, or<strong>de</strong>nados por<br />

puntuación media. Para cada recurso se verán los mismos datos que en <strong>la</strong><br />

página anterior.<br />

10. La aplicación web enviará cookies una so<strong>la</strong> cada vez a cada visitante, <strong>la</strong><br />

primera vez que éste visita el sitio.<br />

93


Salvo cuando se indique otra cosa, se supone que un visitante correspon<strong>de</strong> con<br />

un navegador en un or<strong>de</strong>nador concreto.<br />

Teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Realizar un esquema REST para proporcionar el servicio <strong>de</strong>scrito. Se habrán<br />

<strong>de</strong> especificar <strong>la</strong>s urls empleadas, y cómo reaccionará <strong>la</strong> aplicación cuando<br />

reciba los métodos POST o GET sobre esas urls (no se usarán los métodos<br />

PUT o DELETE). Colocar <strong>la</strong> información en una tab<strong>la</strong>, con <strong>la</strong>s urls en una<br />

columna, los métodos en otra, y <strong>la</strong> <strong>de</strong>scripción <strong>de</strong> lo que realizará <strong>la</strong> aplicación<br />

al recibirlos en <strong>la</strong> tercera. (1.5 puntos)<br />

2. Describe el mo<strong>de</strong>los <strong>de</strong> datos que necesitará esta aplicación. Define <strong>la</strong>s tab<strong>la</strong>s<br />

necesarias y los campos principales. Pue<strong>de</strong>s hacerlo en SQL, en Django-<br />

Python (o simi<strong>la</strong>r, no es importante que se respete <strong>la</strong> sintaxis mientras se<br />

entienda el mo<strong>de</strong>lo <strong>de</strong> datos que propones), o gráficamente en tab<strong>la</strong>s que<br />

indiquen, con columnas, los nombres <strong>de</strong> los campos <strong>de</strong> cada registro. Indicar,<br />

para cada tab<strong>la</strong>, cuál es el campo c<strong>la</strong>ve. (1 punto)<br />

3. Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que un visitante ve <strong>la</strong><br />

lista completa <strong>de</strong> recursos, or<strong>de</strong>nada por puntuaciones, hasta que, <strong>de</strong>spués<br />

<strong>de</strong> pinchar en el en<strong>la</strong>ce correspondiente, ve <strong>la</strong> ficha <strong>de</strong> un recurso. Para cada<br />

interacción HTTP incluye todas <strong>la</strong>s cabeceras que te parezcan relevantes. (1<br />

punto)<br />

4. Supongamos que un visitante realiza <strong>la</strong>s siguientes acciones:<br />

Consulta <strong>de</strong> <strong>la</strong> ficha <strong>de</strong> un recurso.<br />

Cambio <strong>de</strong> nombre <strong>de</strong> ese recurso.<br />

Puntuación <strong>de</strong> ese recurso.<br />

Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que el visitante comienza<br />

hasta que termina estas acciones. Se supone que este visitante ya había<br />

visitado previamente el sitio. Para cada interacción HTTP incluye todas <strong>la</strong>s<br />

cabeceras que te parezcan relevantes. (1 punto)<br />

5. Escribe el código <strong>de</strong>l método que sea invocado para visualizar <strong>la</strong> ficha <strong>de</strong><br />

un recurso. Don<strong>de</strong> te parezca conveniente, y sea razonable en el contexto <strong>de</strong><br />

<strong>la</strong> <strong>asignatura</strong>, pue<strong>de</strong>s usar métodos <strong>de</strong> biblioteca (pero especifica qué hacen<br />

esos métodos). Escribe el código en Python, Python-Django, o algo parecido<br />

(no importa que <strong>la</strong> sintaxis <strong>de</strong>l lenguaje se respete mientras se entienda el<br />

algoritmo). (1 punto)<br />

94


6. Se quiere dar a los visitantes <strong>la</strong> opción <strong>de</strong> “abandonar el sitio”, <strong>de</strong> forma que<br />

si lo vuelven a visitar el sistema les trate como un visitante nuevo. Diseña<br />

y explica un esquema para que esto sea posible (ampliando <strong>de</strong> esta forma <strong>la</strong><br />

funcionalidad <strong>de</strong> <strong>la</strong> aplicación). En caso <strong>de</strong> que utilices nuevas urls, realiza<br />

para el<strong>la</strong>s una tab<strong>la</strong> como <strong>la</strong> <strong>de</strong>l apartado 1. (1 punto)<br />

20.6. 22 <strong>de</strong> junio <strong>de</strong> 2010<br />

Se quiere construir un sitio web (mediante una aplicación web) <strong>de</strong> información<br />

sobre aparatos electrónicos. Para cada aparato, el sistema mantendrá una ficha<br />

con información sobre él. Cada ficha incluye <strong>la</strong> siguiente información:<br />

1. Nombre <strong>de</strong>l aparato (ca<strong>de</strong>na <strong>de</strong> caracteres).<br />

2. Descripción <strong>de</strong>l aparato (unas cuantas líneas <strong>de</strong> texto libre).<br />

3. Url <strong>de</strong> <strong>la</strong> página sobre el aparato en el sitio web <strong>de</strong>l fabricante.<br />

4. Texto HTML correspondiente a <strong>la</strong> página <strong>de</strong>l fabricante <strong>de</strong>l aparato.<br />

5. Si <strong>la</strong> página <strong>de</strong>l fabricante incluye canales RSS, Url <strong>de</strong>l primero <strong>de</strong> ellos.<br />

6. Si existe el canal RSS anterior, su contenido.<br />

7. Comentarios que se hayan podido realizar sobre ese aparato.<br />

Cuando <strong>la</strong>s fichas se muestren en formato HTML, incluirán (para el aparato<br />

correspondiente):<br />

1. Nombre y <strong>de</strong>scripción <strong>de</strong>l aparato.<br />

2. En<strong>la</strong>ce y contenido <strong>de</strong> <strong>la</strong> página sobre el aparato en el sitio <strong>de</strong>l fabricante (el<br />

contenido, embebido en <strong>la</strong> página con el resto <strong>de</strong> <strong>la</strong> ficha)<br />

3. Todos los elementos <strong>de</strong>l canal RSS <strong>de</strong>l aparato, si lo hay.<br />

4. Todos los comentarios <strong>de</strong>l aparato.<br />

El sistema funcionará <strong>de</strong> acuerdo con el siguiente <strong>de</strong>talle:<br />

1. Cualquier visitante <strong>de</strong>l sitio web podrá ver <strong>la</strong>s fichas <strong>de</strong> todos los aparatos<br />

registrados.<br />

2. Cualquier visitante <strong>de</strong>l sitio web podrá dar <strong>de</strong> alta <strong>la</strong> ficha <strong>de</strong> un nuevo aparato.<br />

Si al tratar <strong>de</strong> dar<strong>la</strong> <strong>de</strong> alta, se comprueba que el aparato ya está registrado<br />

(misma url <strong>de</strong> página <strong>de</strong>l fabricante), se impedirá el nuevo registro.<br />

95


3. Cualquier visitante <strong>de</strong>l sitio podrá editar <strong>la</strong> <strong>de</strong>scripción <strong>de</strong>l aparato, cambiándo<strong>la</strong><br />

por una nueva.<br />

4. Cualquier visitante <strong>de</strong>l sitio podrá ver <strong>la</strong> lista histórica <strong>de</strong> <strong>de</strong>scripciones que<br />

ha tenido cualquier aparato (si es que ha tenido más <strong>de</strong> una).<br />

5. Cualquier visitante <strong>de</strong>l sitio podrá poner un comentario sobre cualquier aparato.<br />

6. Cuando un visitante sube información al sitio por primera vez (pue<strong>de</strong> ser<br />

un registro <strong>de</strong> nuevo aparato, una edición <strong>de</strong> <strong>de</strong>scripción <strong>de</strong> aparato, o un<br />

comentario), el sistema le pedirá un nombre. Este nombre no podrá ser igual<br />

a otro usado previamente por cualquier otro visitante. Cuando el visitante<br />

vuelva a subir información <strong>de</strong>s<strong>de</strong> el mismo navegador, el sistema ya no le<br />

pedirá el nombre, y <strong>la</strong> subirá bajo el mismo.<br />

7. Las fichas, los comentarios y <strong>la</strong>s <strong>de</strong>scripciones se verán siempre anotadas con<br />

el nombre <strong>de</strong>l visitante que los creó o editó.<br />

8. En una cierta página será posible ver todos los aparatos registrados. Para<br />

cada aparato se verá el nombre <strong>de</strong>l aparato y un en<strong>la</strong>ce a su ficha.<br />

9. En esa misma página será posible realizar búsquedas <strong>de</strong> aparatos cuyo nombre<br />

contenga una cierta ca<strong>de</strong>na <strong>de</strong> caracteres. Cuando se use esta posibilidad,<br />

en lugar se verse todos los aparatos registrados se verán sólo aquellos cuyo<br />

nombre contenga esa ca<strong>de</strong>na.<br />

10. La aplicación web enviará o analizará cookies u otras formas <strong>de</strong> re<strong>la</strong>cionar<br />

invocaciones <strong>de</strong> recursos sólo cuando sea preciso para ofrecer <strong>la</strong> funcionalidad<br />

mencionada.<br />

Salvo cuando se indique otra cosa, se supone que un visitante correspon<strong>de</strong> con<br />

un navegador en un or<strong>de</strong>nador concreto.<br />

Cada vez que <strong>la</strong> aplicación reciba información <strong>de</strong> otro sitio web, <strong>la</strong> almacenará<br />

para mejorar el tiempo <strong>de</strong> respuesta al usuario (no bajándo<strong>la</strong> <strong>de</strong> nuevo cuando<br />

<strong>la</strong> tenga que volver a mostrar). La aplicación mostrará al usuario cuándo fue<br />

recogida cualquier información almacenada que le presente, y proporcionará mecanismos<br />

REST en el interfaz <strong>de</strong> usuario para que cualquiera pueda pedir que se<br />

le muestre una versión actualizada.<br />

Teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Realizar un esquema REST para proporcionar el servicio <strong>de</strong>scrito. Se habrán<br />

<strong>de</strong> especificar <strong>la</strong>s urls empleadas, y cómo reaccionará <strong>la</strong> aplicación cuando<br />

96


eciba los métodos POST o GET sobre esas urls (no se usarán los métodos<br />

PUT o DELETE). Colocar <strong>la</strong> información en una tab<strong>la</strong>, con <strong>la</strong>s urls en<br />

una columna, los métodos en otra, y <strong>la</strong> <strong>de</strong>scripción <strong>de</strong> lo que realizará <strong>la</strong><br />

aplicación al recibirlos en <strong>la</strong> tercera. Téngase en cuenta que cuando se reciba<br />

<strong>la</strong> invocación <strong>de</strong> un método, es posible que haya que realizar acciones externas<br />

sobre otros sitios web.(1.5 puntos)<br />

2. Describe el mo<strong>de</strong>los <strong>de</strong> datos que necesitará esta aplicación. Define <strong>la</strong>s tab<strong>la</strong>s<br />

necesarias y los campos principales. Pue<strong>de</strong>s hacerlo en SQL o en Django-<br />

Python (o simi<strong>la</strong>r, no es importante que se respete <strong>la</strong> sintaxis mientras se<br />

entienda el mo<strong>de</strong>lo <strong>de</strong> datos que propones). (1 punto)<br />

3. Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que un visitante ve <strong>la</strong><br />

lista completa <strong>de</strong> aparatos hasta que, <strong>de</strong>spués <strong>de</strong> indicar una cierta ca<strong>de</strong>na <strong>de</strong><br />

caracteres, ve <strong>la</strong> lista <strong>de</strong> aquellos cuyo nombre contiene esa ca<strong>de</strong>na. Para cada<br />

interacción HTTP incluye todas <strong>la</strong>s cabeceras que te parezcan relevantes. (1<br />

punto)<br />

4. Supongamos que un visitante realiza <strong>la</strong>s siguientes acciones:<br />

Consulta <strong>de</strong> <strong>la</strong> ficha <strong>de</strong> un aparato.<br />

Comentario a <strong>la</strong> ficha <strong>de</strong> ese mismo aparato.<br />

Creación <strong>de</strong> un nuevo aparato.<br />

Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que el visitante comienza<br />

hasta que termina estas acciones. Se supone que este visitante es <strong>la</strong><br />

primera vez que visita el sitio. Para cada interacción HTTP incluye todas<br />

<strong>la</strong>s cabeceras que te parezcan relevantes. (1 punto)<br />

5. Escribe el código <strong>de</strong>l método que sea invocado cuando se reciba una invocación<br />

<strong>de</strong> un visitante con los datos para registrar un nuevo aparato. Don<strong>de</strong><br />

te parezca conveniente, y sea razonable en el contexto <strong>de</strong> <strong>la</strong> <strong>asignatura</strong>, pue<strong>de</strong>s<br />

usar métodos <strong>de</strong> biblioteca (pero especifica qué hacen esos métodos).<br />

Escribe el código en Python, Python-Django, o algo parecido (no importa<br />

que <strong>la</strong> sintaxis <strong>de</strong>l lenguaje se respete mientras se entienda el algoritmo). (1<br />

punto)<br />

6. Se quiere dar a los visitantes <strong>la</strong> opción <strong>de</strong> “reservar” su nombre, <strong>de</strong> forma que<br />

puedan seguir usándolo cuando estén en otro navegador. Para ello, podrán<br />

usar una cierta url que les <strong>de</strong>volverá una ca<strong>de</strong>na <strong>de</strong> caracteres, que podrán<br />

incluir en un formu<strong>la</strong>rio cuando quieran i<strong>de</strong>ntificarse <strong>de</strong>s<strong>de</strong> otro navegador.<br />

Indica qué condiciones ha <strong>de</strong> cumplir esa ca<strong>de</strong>na <strong>de</strong> caracteres, y diseña y<br />

97


explica un esquema para que este esquema pueda funcionar. Para <strong>la</strong>s nuevas<br />

urls implicadas, o para <strong>la</strong>s antiguas que cambien, rellena una tab<strong>la</strong> como <strong>la</strong><br />

<strong>de</strong>l apartado 1. (1 punto)<br />

20.7. 13 <strong>de</strong> diciembre <strong>de</strong> 2010<br />

Se quiere construir un sitio web (mediante una aplicación web) para seguir<br />

comentarios en un sitio <strong>de</strong> micromensajes (microblogging), I<strong>de</strong>nti.ca. L<strong>la</strong>maremos<br />

al sitio “FollowTheTag”. El sitio servirá para ver los micromensajes que se han<br />

puesto con ciertas etiquetas (tags). En los sitios <strong>de</strong> micromensajes, <strong>la</strong>s etiquetas se<br />

marcan poniendo “#” <strong>de</strong><strong>la</strong>nte <strong>de</strong>l nombre <strong>de</strong> <strong>la</strong> etiqueta, como parte <strong>de</strong>l mensaje.<br />

En el caso concreto <strong>de</strong> I<strong>de</strong>nti.ca, todos los micromensajes que se han puesto con<br />

una <strong>de</strong>terminada etiqueta (“etiqueta”) están disponibles, como canal RSS, en <strong>la</strong><br />

url http://i<strong>de</strong>nti.ca/tag/etiqueta/rss.<br />

FollowTheTag funcionará <strong>de</strong> acuerdo con el siguiente <strong>de</strong>talle:<br />

1. Los micromensajes que tienen una cierta etiqueta se podrán consultar en una<br />

url específica (para esa etiqueta) <strong>de</strong> FollowTheTag.<br />

2. Cualquier visitante <strong>de</strong> FollowTheTag podrá ver los micromensajes <strong>de</strong> cualquier<br />

etiqueta que quiera, consultando <strong>la</strong> url correspondiente. Si los micromensajes<br />

<strong>de</strong> <strong>la</strong> etiqueta indicada no habían sido solicitados nunca antes en<br />

FollowTheTag, <strong>la</strong> aplicación bajará <strong>de</strong> I<strong>de</strong>nti.ca el canal RSS correspondiente,<br />

actualizará con sus contenidos <strong>la</strong> tab<strong>la</strong> <strong>de</strong> micromensajes en su base <strong>de</strong><br />

datos, y mostrará los micromensajes recién incorporados. Si ya habían sido<br />

solicitados, mostrará los que tenga en <strong>la</strong> tab<strong>la</strong> mencionada.<br />

3. Para cada etiqueta, FollowTheTag ofrecerá una url que permitirá actualizar<br />

los micromensajes <strong>de</strong> esa etiqueta, bajando el canal RSS correspondiente <strong>de</strong><br />

I<strong>de</strong>nti.ca. Como respuesta a <strong>la</strong> consulta <strong>de</strong> esa url, el navegador recibirá el<br />

mensaje “Etiqueta actualizada”.<br />

4. Para cada etiqueta, FollowTheTag ofrecerá una url en <strong>la</strong> que se podrá “puntuar”<br />

<strong>la</strong> etiqueta con entre 1 y 7 puntos. En esa misma url se podrá ver el<br />

número <strong>de</strong> puntos que ha recibido <strong>la</strong> etiqueta.<br />

5. Para cada etiqueta, FollowTheTag ofrecerá una url que permitirá conocer el<br />

número <strong>de</strong> visitas, el número <strong>de</strong> visitantes únicos y el número <strong>de</strong> puntos que<br />

ha tenido esa etiqueta,<br />

6. Si un visitante consulta <strong>la</strong> página principal <strong>de</strong> FollowTheTag, se verá <strong>la</strong> lista<br />

<strong>de</strong> etiquetas que ha visitado ese visitante en el pasado, <strong>la</strong> lista <strong>de</strong> últimas<br />

etiquetas visitadas (<strong>de</strong>s<strong>de</strong> cualquier navegador), <strong>la</strong> lista <strong>de</strong> etiquetas más<br />

98


visitadas (en número absoluto <strong>de</strong> visitas), <strong>la</strong> lista <strong>de</strong> etiquetas que más visitantes<br />

únicos han tenido (en número absoluto <strong>de</strong> visitantes) y <strong>la</strong> lista <strong>de</strong> <strong>la</strong>s<br />

etiquetas más puntuadas.<br />

Salvo cuando se indique otra cosa, se supone que un visitante correspon<strong>de</strong> con<br />

un navegador en un or<strong>de</strong>nador concreto.<br />

Teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Diseña un esquema REST para proporcionar el servicio <strong>de</strong>scrito. Se habrán<br />

<strong>de</strong> especificar <strong>la</strong>s urls empleadas, y cómo reaccionará <strong>la</strong> aplicación cuando<br />

reciba los métodos POST o GET sobre esas urls (no se usarán los métodos<br />

PUT o DELETE). Colocar <strong>la</strong> información en una tab<strong>la</strong>, con <strong>la</strong>s urls en<br />

una columna, los métodos en otra, y <strong>la</strong> <strong>de</strong>scripción <strong>de</strong> lo que realizará <strong>la</strong><br />

aplicación al recibirlos en <strong>la</strong> tercera. Téngase en cuenta que cuando se reciba<br />

<strong>la</strong> invocación <strong>de</strong> un método, es posible que haya que realizar acciones externas<br />

sobre otros sitios web.(1 punto)<br />

2. Describe el mo<strong>de</strong>lo <strong>de</strong> datos que necesitará esta aplicación. Define <strong>la</strong>s tab<strong>la</strong>s<br />

necesarias y los campos principales. Hazlo <strong>de</strong> forma lo más simi<strong>la</strong>r posible<br />

a lo que tendrías que escribir en el fichero mo<strong>de</strong>ls.py en Django (aunque no<br />

es importante que se respete <strong>la</strong> sintaxis mientras se entienda el mo<strong>de</strong>lo <strong>de</strong><br />

datos que propones). (1 punto)<br />

3. Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que un visitante ve<br />

<strong>la</strong> página principal <strong>de</strong>l sitio hasta que, <strong>de</strong>spués <strong>de</strong> picar en <strong>la</strong> etiqueta más<br />

visitada, ve los micromensajes <strong>de</strong> esa etiqueta. Para cada interacción HTTP<br />

incluye todas <strong>la</strong>s cabeceras que te parezcan relevantes. Supóngase que <strong>la</strong><br />

visita se hace <strong>de</strong>s<strong>de</strong> un navegador que nunca había visitado el sitio antes.(1<br />

punto)<br />

4. Supongamos que un visitante realiza <strong>la</strong>s siguientes acciones:<br />

Consulta <strong>de</strong> <strong>la</strong> url <strong>de</strong> una etiqueta que ya ha sido previamente consultada.<br />

Acceso a <strong>la</strong> url <strong>de</strong> actualización <strong>de</strong> esa etiqueta.<br />

Nueva consulta <strong>de</strong> <strong>la</strong> url <strong>de</strong> <strong>la</strong> misma etiqueta.<br />

Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que el visitante comienza<br />

hasta que termina estas acciones. Para cada interacción HTTP incluye<br />

todas <strong>la</strong>s cabeceras que te parezcan relevantes. Supóngase que <strong>la</strong> visita se<br />

hace <strong>de</strong>s<strong>de</strong> un navegador que nunca había visitado el sitio antes.(1 punto)<br />

99


5. ¿Pue<strong>de</strong> ofrecerse en <strong>la</strong> página principal <strong>la</strong> lista <strong>de</strong> etiquetas visitadas pro le<br />

visitante en el pasado sin almacenar esa lista en el servidor Si <strong>la</strong> respuesta es<br />

no, ¿por qué Si <strong>la</strong> respuesta es sí, ¿cómo ¿con alguna limitación(1 punto)<br />

6. Describe (en pseudocódigo, en Python o en Python-Django) el código <strong>de</strong> <strong>la</strong><br />

función que aten<strong>de</strong>ría <strong>la</strong>s invocaciones <strong>de</strong>l recurso que sirve para puntuar una<br />

etiqueta. Don<strong>de</strong> te parezca conveniente, y sea razonable en el contexto <strong>de</strong><br />

<strong>la</strong> <strong>asignatura</strong>, pue<strong>de</strong>s usar métodos <strong>de</strong> biblioteca (pero especifica qué hacen<br />

esos métodos). (1 punto)<br />

7. Describe qué mecanismo usa tu diseño para llevar <strong>la</strong> cuenta <strong>de</strong> <strong>la</strong>s visitas y<br />

los visitantes únicos a cada etiqueta, <strong>de</strong> forma que <strong>la</strong> página principal pueda<br />

or<strong>de</strong>nar<strong>la</strong>s según estos criterios. (1 punto)<br />

En todos los apartados, ten en cuenta que tu respuesta <strong>de</strong>be consi<strong>de</strong>rar toda<br />

<strong>la</strong> funcionalidad que ofrece el servicio, y permitir que ésta pueda proporcionarse.<br />

En todo el enunciado, se entien<strong>de</strong> que “visita” es el acceso a un recurso <strong>de</strong>l<br />

servicio FollowTheTag.<br />

20.8. 20 <strong>de</strong> junio <strong>de</strong> 2011<br />

Se quiere construir un sitio web (mediante una aplicación web) para seguir<br />

comentarios en un sitio <strong>de</strong> micromensajes (microblogging), I<strong>de</strong>nti.ca. L<strong>la</strong>maremos<br />

al sitio “FollowTheDenter”. El sitio servirá para ver los micromensajes que ha<br />

puesto un “<strong>de</strong>nter” (usuario <strong>de</strong> i<strong>de</strong>ntica) puesto con ciertas etiquetas (tags). En el<br />

caso concreto <strong>de</strong> I<strong>de</strong>nti.ca, los últimos micromensajes que ha puesto un <strong>de</strong>nter están<br />

disponibles, como canal RSS, en <strong>la</strong> url http://i<strong>de</strong>nti.ca/<strong>de</strong>nter/rss (para el<br />

usuario “<strong>de</strong>nter”).<br />

FollowTheDenter funcionará <strong>de</strong> acuerdo con el siguiente <strong>de</strong>talle:<br />

1. Los micromensajes puestos por un cierto <strong>de</strong>nter se podrán consultar en una<br />

url específica (para ese <strong>de</strong>nter) <strong>de</strong> FollowTheDenter.<br />

2. Cualquier visitante <strong>de</strong> FollowTheDenter podrá ver los micromensajes <strong>de</strong> cualquier<br />

<strong>de</strong>nter que quiera, consultando <strong>la</strong> url correspondiente. Si los micromensajes<br />

<strong>de</strong>l <strong>de</strong>nter indicado no habían sido solicitados nunca antes en FollowTheDenter,<br />

<strong>la</strong> aplicación bajará <strong>de</strong> I<strong>de</strong>nti.ca el canal RSS correspondiente,<br />

actualizará con sus contenidos <strong>la</strong> tab<strong>la</strong> <strong>de</strong> micromensajes en su base <strong>de</strong> datos,<br />

y mostrará los micromensajes recién incorporados. Si ya habían sido<br />

solicitados, mostrará los que tenga en <strong>la</strong> tab<strong>la</strong> mencionada.<br />

100


3. Para cada <strong>de</strong>nter, FollowTheDenter ofrecerá una url que permitirá actualizar<br />

los micromensajes <strong>de</strong> ese <strong>de</strong>nter, bajando el canal RSS correspondiente <strong>de</strong><br />

I<strong>de</strong>nti.ca. Como respuesta a <strong>la</strong> consulta <strong>de</strong> esa url, el navegador recibirá una<br />

página que tendrá so<strong>la</strong>mente el mensaje “Mensajes <strong>de</strong> <strong>de</strong>nter actualizados”<br />

(siendo “<strong>de</strong>nter” el <strong>de</strong>nter en cuestión).<br />

4. Para cada <strong>de</strong>nter, FollowTheDenter ofrecerá una url en <strong>la</strong> que se podrá “puntuar”<br />

el <strong>de</strong>nter con entre 1 y 5 puntos. En esa misma url se podrá ver el<br />

número total <strong>de</strong> puntos que ha recibido el <strong>de</strong>nter hasta el momento, y el<br />

número <strong>de</strong> votaciones que ha tenido.<br />

5. Para cada <strong>de</strong>nter, FollowTheDenter ofrecerá una url que permitirá conocer<br />

el número <strong>de</strong> visitas, el número <strong>de</strong> visitantes únicos y el número <strong>de</strong> puntos<br />

que ha tenido ese <strong>de</strong>nter en FollowTheDenter,<br />

6. Si un visitante consulta <strong>la</strong> página principal <strong>de</strong> FollowTheDenter, se verá <strong>la</strong><br />

lista <strong>de</strong> <strong>de</strong>nters que ha visitado en el pasado, <strong>la</strong> lista <strong>de</strong> últimos <strong>de</strong>nters<br />

visitadas (por el total <strong>de</strong> visitantes <strong>de</strong>l sitio), <strong>la</strong> lista <strong>de</strong> últimos <strong>de</strong>nters<br />

“incluidos” en el sitio, <strong>la</strong> lista <strong>de</strong> <strong>de</strong>nters que más visitantes únicos han<br />

tenido en <strong>la</strong>s últimas 24 horas y <strong>la</strong> lista <strong>de</strong> <strong>la</strong>s <strong>de</strong>nters más puntuados.<br />

Salvo cuando se indique otra cosa, se supone que un visitante correspon<strong>de</strong> con<br />

un navegador en un or<strong>de</strong>nador concreto.<br />

Teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Diseña un esquema REST para proporcionar el servicio <strong>de</strong>scrito. Se habrán<br />

<strong>de</strong> especificar <strong>la</strong>s urls empleadas, y cómo reaccionará <strong>la</strong> aplicación cuando<br />

reciba los métodos POST o GET sobre esas urls (no se usarán los métodos<br />

PUT o DELETE). Colocar <strong>la</strong> información en una tab<strong>la</strong>, con <strong>la</strong>s urls en<br />

una columna, los métodos en otra, y <strong>la</strong> <strong>de</strong>scripción <strong>de</strong> lo que realizará <strong>la</strong><br />

aplicación al recibirlos en <strong>la</strong> tercera. Téngase en cuenta que cuando se reciba<br />

<strong>la</strong> invocación <strong>de</strong> un método, es posible que haya que realizar acciones externas<br />

sobre otros sitios web: es importante, en ese caso, especificar el HTTP que<br />

se realizará para acce<strong>de</strong>r a esos otros sitios.(1 punto)<br />

2. Describe el mo<strong>de</strong>lo <strong>de</strong> datos que necesitará esta aplicación. Define <strong>la</strong>s tab<strong>la</strong>s<br />

necesarias y los campos principales. Hazlo <strong>de</strong> forma lo más simi<strong>la</strong>r posible<br />

a lo que tendrías que escribir en el fichero mo<strong>de</strong>ls.py en Django (aunque no<br />

es importante que se respete <strong>la</strong> sintaxis mientras se entienda el mo<strong>de</strong>lo <strong>de</strong><br />

datos que propones). (1 punto)<br />

3. Para cada url especificada en el primer apartado, explica qué tab<strong>la</strong>s <strong>de</strong>l<br />

apartado anterior habrá que acce<strong>de</strong>r para po<strong>de</strong>r realizar <strong>la</strong> funcionalidad<br />

que implementa cada una <strong>de</strong> el<strong>la</strong>s. (1 punto)<br />

101


4. Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que un visitante actualiza<br />

los mensajes <strong>de</strong> un <strong>de</strong>nter, hasta que ve en su navegador <strong>la</strong> página<br />

correspondiente a ese <strong>de</strong>nter (con sus mensajes). Para cada interacción<br />

HTTP (sea entre los or<strong>de</strong>nadores que sea) incluye todas <strong>la</strong>s cabeceras que te<br />

parezcan relevantes. Supóngase que el visitante ya ha vistado anteriormente<br />

el sitio.(1 punto)<br />

5. Supongamos que un visitante realiza <strong>la</strong>s siguientes acciones:<br />

Consulta <strong>de</strong> <strong>la</strong> url <strong>de</strong> un <strong>de</strong>nter que ya ha sido previamente consultado.<br />

Al cabo <strong>de</strong> 10 minutos, nueva consulta <strong>de</strong> <strong>la</strong> misma url.<br />

Puntuación <strong>de</strong> ese <strong>de</strong>nter.<br />

Describe <strong>la</strong>s interacciones HTTP que ocurrirán <strong>de</strong>s<strong>de</strong> que el visitante comienza<br />

hasta que termina estas acciones. Para cada interacción HTTP incluye<br />

todas <strong>la</strong>s cabeceras que te parezcan relevantes. Supóngase que <strong>la</strong> visita se<br />

hace <strong>de</strong>s<strong>de</strong> un navegador que nunca había visitado el sitio antes.(1 punto)<br />

6. ¿Pue<strong>de</strong> ofrecerse en <strong>la</strong> página principal <strong>la</strong> lista <strong>de</strong> <strong>de</strong>nters visitados por el<br />

último visitante <strong>de</strong>l sitio antes <strong>de</strong>l actual ¿Cómo se podría hacer (1 punto)<br />

7. Describe qué mecanismo usa tu diseño para llevar <strong>la</strong> cuenta <strong>de</strong> <strong>la</strong>s visitas y<br />

los visitantes únicos a cada <strong>de</strong>nter, <strong>de</strong> forma que <strong>la</strong> página principal pueda<br />

or<strong>de</strong>nar<strong>la</strong>s según estos criterios. (1 punto)<br />

En todos los apartados, ten en cuenta que tu respuesta <strong>de</strong>be consi<strong>de</strong>rar toda<br />

<strong>la</strong> funcionalidad que ofrece el servicio, y permitir que ésta pueda proporcionarse.<br />

En todo el enunciado, se entien<strong>de</strong> que “visita” es el acceso a un recurso <strong>de</strong>l<br />

servicio FollowTheDenter.<br />

20.9. 12 <strong>de</strong> diciembre <strong>de</strong> 2011<br />

Se quiere construir un sitio web (mediante una aplicación web) para crear<br />

resúmenes <strong>de</strong>l sitio <strong>de</strong> música Jamendo. Jamendo es un sitio web que ofrece grabaciones<br />

<strong>de</strong> música en varios formatos (entre ellos, MP3) <strong>de</strong> los artistas que <strong>la</strong> han<br />

subido previamente al sitio. Nuestro sitio web, que se l<strong>la</strong>mará Mimusica, permitirá<br />

crear resúmenes <strong>de</strong> <strong>la</strong> música que interesa a los usuarios, utilizando información<br />

<strong>de</strong> Jamendo.<br />

La API REST (simplificada) <strong>de</strong> Jamendo nos proporciona urls para <strong>la</strong> <strong>de</strong>scarga<br />

<strong>de</strong> canales RSS con información sobre los álbumes <strong>de</strong> un artista y los cortes (tracks)<br />

<strong>de</strong> un álbum como se indica a continuación.<br />

102


Para obtener el canal RSS correspondiente a los álbumes <strong>de</strong>l artista “Both”.<br />

se pue<strong>de</strong> invocar <strong>la</strong> siguiente url:<br />

http://www.jamendo.com/get/album/list/artist/page/rss2/names=Both<br />

Su invocación <strong>de</strong>volverá el contenido que se indica a continuación (lo l<strong>la</strong>maremos<br />

“canal <strong>de</strong> artista”). En él pue<strong>de</strong> verse <strong>la</strong> lista <strong>de</strong> álbumes para ese artista<br />

(como elementos “item”), y para cada uno <strong>de</strong> ellos su título (“guid”), un en<strong>la</strong>ce a<br />

su página en Jamendo (“link”), un en<strong>la</strong>ce a <strong>la</strong> imagen <strong>de</strong> su portada (“enclosure”),<br />

etc. En particu<strong>la</strong>r, <strong>la</strong> última parte <strong>de</strong>l elemento “link” <strong>de</strong>l álbum (lo que va entre<br />

los dos “/” finales) es el i<strong>de</strong>ntificador <strong>de</strong>l álbum.<br />

<br />

<br />

Jamendo<br />

http://www.jamendo.com/<br />

Open your ears<br />

<br />

http://www.jamendo.com/<br />

http://imgjam.com/logo/simple1.gif<br />

<br />

Sun, 11 Dec 2011 23:44:36 +0100<br />

<br />

Both : Simple Exercice<br />

http://www.jamendo.com/album/33/<br />

Simple Exercice<br />

Both<br />

<br />

http://www.jamendo.com/album/33sub=reviews<br />

<br />

... <br />

<br />

Para obtener el canal RSS correspondiente a los cortes (tracks) <strong>de</strong>l álbum cuyo<br />

i<strong>de</strong>ntificador es “33” se pue<strong>de</strong> invocar <strong>la</strong> siguiente url:<br />

http://www.jamendo.com/get/track/list/album/page/rss2/ids=33<br />

Su invocación <strong>de</strong>volverá el contenido que se indica a continuación (lo l<strong>la</strong>maremos<br />

“canal <strong>de</strong> álbum”). En él pue<strong>de</strong> verse <strong>la</strong> lista <strong>de</strong> cortes para ese álbum (como<br />

elementos “item”), y para cada uno <strong>de</strong> ellos su título (“title”), un en<strong>la</strong>ce a su página<br />

en Jamendo (“link”), un en<strong>la</strong>ce al fichero MP3 con el corte (“media:content”),<br />

etc.<br />

<br />

103


Jamendo<br />

http://www.jamendo.com/<br />

... <br />

<br />

Simple Exercice<br />

http://www.jamendo.com/track/241/<br />

<br />

<br />

<br />

... <br />

<br />

El funcionamiento <strong>de</strong> Mimusica seguirá el siguiente <strong>de</strong>talle:<br />

1. Los que visitan el sitio podrán tener cuenta en él (les l<strong>la</strong>maremos “usuarios”,<br />

una vez se han autenticado) o no (les l<strong>la</strong>maremos visitantes).<br />

2. La apertura <strong>de</strong> cuentas no es parte <strong>de</strong> <strong>la</strong> funcionalidad a implementar, se<br />

supone que se hace mediante algún procedimiento previo.<br />

3. Cada usuario <strong>de</strong> Mimusica podrá crear su propio resumen <strong>de</strong> Jamendo, eligiendo<br />

a los artistas <strong>de</strong> Jamendo que le gusten. Para cada álbum <strong>de</strong> cada<br />

artista elegido, Mimusica almacenará <strong>la</strong> imagen <strong>de</strong> su carátu<strong>la</strong> (<strong>la</strong> imagen, no<br />

el en<strong>la</strong>ce a <strong>la</strong> imagen), su título, <strong>la</strong> lista <strong>de</strong> los títulos <strong>de</strong> sus cortes (tracks)<br />

y <strong>la</strong> url para <strong>de</strong>scargar el MP3 <strong>de</strong> cada uno <strong>de</strong> ellos.<br />

4. Para cada usuario se generará su página <strong>de</strong> resumen en HTML en <strong>la</strong> que<br />

aparecerá el nombre <strong>de</strong>l usuario, <strong>la</strong> lista <strong>de</strong> los artistas que ha elegido ese<br />

usuario, y <strong>la</strong> lista <strong>de</strong> los títulos <strong>de</strong> los álbumes <strong>de</strong> esos artistas. Para cada<br />

álbum se mostrará a<strong>de</strong>más <strong>la</strong> imagen <strong>de</strong> su carátu<strong>la</strong>.<br />

5. En <strong>la</strong> página anterior junto a cada álbum habrá un en<strong>la</strong>ce que, al picarlo,<br />

provocará que se muestre (previa consulta a Mimusica) <strong>la</strong> lista <strong>de</strong> títulos<br />

<strong>de</strong> los cortes (tracks) <strong>de</strong> ese álbum como en<strong>la</strong>ces para <strong>de</strong>scarga <strong>de</strong> los MP3<br />

correspondientes.<br />

6. Cuando <strong>la</strong> página <strong>de</strong> resumen <strong>de</strong> un usuario es consultada por un visitante<br />

mostrará exclusivamente lo especificado en los dos puntos anteriores.<br />

7. Cuando <strong>la</strong> página <strong>de</strong> resumen <strong>de</strong> un usuario es consultada por otro usuario<br />

diferente mostrará a<strong>de</strong>más un en<strong>la</strong>ce, junto a cada artista, para po<strong>de</strong>r<br />

seleccionarlo para el resumen propio. Cuando se realiza esta selección, el<br />

104


usuario ve un mensaje en <strong>la</strong> página (sin recargar<strong>la</strong> entera, y realizando para<br />

<strong>la</strong> operación una so<strong>la</strong> interacción HTTP) indicando que el artista ha sido<br />

añadido.<br />

8. Cuando <strong>la</strong> página <strong>de</strong> resumen <strong>de</strong> un usuario es consultada por el propio<br />

usuario, ese en<strong>la</strong>ce extra será para eliminar al artista <strong>de</strong>l resumen. A<strong>de</strong>más,<br />

<strong>la</strong> página incluirá un formu<strong>la</strong>rio en el que se podrá escribir el nombre <strong>de</strong> un<br />

artista para seleccionarlo para el resumen. Cuando se selecciona un artista<br />

para el resumen, si ya está en <strong>la</strong> base <strong>de</strong> datos se muestran sus álbumes<br />

en <strong>la</strong> página (sin recargar<strong>la</strong> entera, y realizando para <strong>la</strong> operación una so<strong>la</strong><br />

interacción HTTP). Si el artista no está en <strong>la</strong> base <strong>de</strong> datos, se indica en<br />

<strong>la</strong> página (<strong>de</strong> nuevo, sin recargar<strong>la</strong> entera, y realizando para <strong>la</strong> operación<br />

una so<strong>la</strong> interacción HTTP), y se programa una <strong>de</strong> Jamendo <strong>de</strong> los datos<br />

necesarios para incluirlos en <strong>la</strong> base <strong>de</strong> datos.<br />

9. Para cada usuario, Mimusica mantendrá a<strong>de</strong>más <strong>la</strong> página <strong>de</strong> estadísticas,<br />

con el nombre <strong>de</strong> recurso “/stats/”, sólo accesible por ese usuario (para los<br />

<strong>de</strong>más dará un mensaje <strong>de</strong> acceso <strong>de</strong>negado). En esa página aparecerá el<br />

número <strong>de</strong> veces que <strong>la</strong> página <strong>de</strong> resumen ha sido consultada, y para cada<br />

uno <strong>de</strong> los álbumes que ha sido incluido en el<strong>la</strong> en algún momento, el número<br />

<strong>de</strong> veces que se ha pedido un listado <strong>de</strong> sus cortes.<br />

10. La página principal <strong>de</strong> Mimusica mostrará un listado <strong>de</strong> los usuarios <strong>de</strong>l sitio,<br />

con en<strong>la</strong>ces (para cada uno <strong>de</strong> ellos) a su página <strong>de</strong> resumen. A<strong>de</strong>más, si <strong>la</strong><br />

consulta un usuario, mostrará un en<strong>la</strong>ce a su página con sus estadísticas.<br />

Salvo cuando se indique otra cosa, se supone que un visitante correspon<strong>de</strong> con<br />

un navegador en un or<strong>de</strong>nador concreto.<br />

Teniendo en cuenta los requisitos anteriores, se pi<strong>de</strong>:<br />

1. Diseña un esquema REST para proporcionar el servicio <strong>de</strong>scrito. Se habrán<br />

<strong>de</strong> especificar los nombres <strong>de</strong> recurso empleados, y cómo reaccionará <strong>la</strong> aplicación<br />

cuando reciba los métodos POST o GET sobre esas urls (no se usarán<br />

los métodos PUT o DELETE). Coloca <strong>la</strong> información en una tab<strong>la</strong>, con <strong>la</strong>s<br />

urls en una columna, los métodos en otra, y <strong>la</strong> <strong>de</strong>scripción <strong>de</strong> lo que realizará<br />

<strong>la</strong> aplicación al recibirlos en <strong>la</strong> tercera. Para este punto no tengas en<br />

cuenta el recurso “/stats/”, ni lo que pueda hacer falta para que funcione.(2<br />

puntos)<br />

2. Describe el mo<strong>de</strong>lo <strong>de</strong> datos que necesitará esta aplicación. Define <strong>la</strong>s tab<strong>la</strong>s<br />

necesarias y los campos principales. Hazlo <strong>de</strong> forma lo más simi<strong>la</strong>r posible<br />

a lo que tendrías que escribir en el fichero mo<strong>de</strong>ls.py en Django (aunque no<br />

105


es importante que se respete <strong>la</strong> sintaxis mientras se entienda el mo<strong>de</strong>lo <strong>de</strong><br />

datos que propones). Pue<strong>de</strong> suponerse que el sistema ya proporciona una<br />

tab<strong>la</strong> <strong>de</strong> usuarios, con (al menos) dos campos: “Id” (i<strong>de</strong>ntificador único <strong>de</strong><br />

usuario, que a<strong>de</strong>más será c<strong>la</strong>ve primaria) y “Name” (nombre <strong>de</strong>l usuario,<br />

no necesariamente único). Para este punto no tengas en cuenta el recurso<br />

“/stats/”, ni lo que pueda hacer falta para que funcione.(1 punto)<br />

3. Para cada campo <strong>de</strong> <strong>la</strong> base <strong>de</strong> datos que provenga <strong>de</strong> un canal RSS <strong>de</strong><br />

Jamendo, indica <strong>de</strong> qué elemento <strong>de</strong> qué tipo <strong>de</strong> canal (entre los especificados<br />

anteriormente) provendrá.(1 punto)<br />

4. Describe <strong>la</strong>s interacciones HTTP que ocurrirán en el siguiente escenario. Un<br />

visitante que está viendo en su navegador <strong>la</strong> página principal <strong>de</strong> Mimusica<br />

pica sobre el resumen <strong>de</strong> un usuario. Cuando lo ve, pica para <strong>de</strong>splegar <strong>la</strong><br />

lista <strong>de</strong> cortes <strong>de</strong> un álbum. El escenario termina cuando el usuario ve <strong>la</strong><br />

lista <strong>de</strong> cortes.(2 puntos)<br />

5. Describe <strong>la</strong>s interacciones HTTP que ocurrirán en el siguiente escenario. Un<br />

usuario que está viendo en su navegador <strong>la</strong> página principal <strong>de</strong> Mimusica<br />

pica sobre <strong>la</strong> página <strong>de</strong> resumen <strong>de</strong> otro usuario. Cuando lo ve, pica sobre<br />

el en<strong>la</strong>ce para elegir un artista para su propio resumen. El escenario termina<br />

cuando el usuario ve anotado en esta página que el artista ha sido elegido<br />

para su resumen.(2 puntos)<br />

6. Indica <strong>la</strong>s interacciones HTTP que tendrán lugar entre Mimusica, Jamendo y<br />

(si es caso) otros servidores HTTP cuando un usuario elija para su resumen<br />

un artista que no está en <strong>la</strong> base <strong>de</strong> datos <strong>de</strong> Mimusica, pero sí está en<br />

Jamendo.(1 punto)<br />

7. Describe cómo recogerás <strong>la</strong> información necesaria para generar el contenido a<br />

<strong>de</strong>volver cuando se reciba un GET <strong>de</strong>l recurso “/stats”, incluyendo <strong>la</strong>s tab<strong>la</strong>s<br />

necesarias en <strong>la</strong> base <strong>de</strong> datos. (1 punto)<br />

En todos los apartados, ten en cuenta que tu respuesta <strong>de</strong>be consi<strong>de</strong>rar toda<br />

<strong>la</strong> funcionalidad que ofrece el servicio, y permitir que ésta pueda proporcionarse.<br />

En <strong>la</strong>s respuestas don<strong>de</strong> <strong>de</strong>scribas interacciones HTTP indica para cada una<br />

<strong>de</strong> el<strong>la</strong>s c<strong>la</strong>ramente y en este or<strong>de</strong>n:<br />

La primera línea <strong>de</strong> <strong>la</strong> petición HTTP<br />

Si lo hay, el contenido <strong>de</strong> <strong>la</strong> petición<br />

La primera línea <strong>de</strong> <strong>la</strong> respuesta HTTP<br />

106


Si lo hay, el contenido <strong>de</strong> <strong>la</strong> respuesta<br />

Una brevísima explicación <strong>de</strong> para qué se usa <strong>la</strong> interacción<br />

Tanto en <strong>la</strong> petición como en <strong>la</strong> respuesta, <strong>la</strong>s cabeceras con cookies, si es que<br />

fueran necesarias para <strong>la</strong> funcionalidad <strong>de</strong>l escenario que se está <strong>de</strong>scribiendo.<br />

A<strong>de</strong>más, asegúrate <strong>de</strong> que <strong>de</strong>scribes <strong>la</strong>s interacciones HTTP en el or<strong>de</strong>n en que<br />

ocurrirían en el escenario.<br />

107


21. Evaluación<br />

Parámetros generales:<br />

Teoría (obligatorio): 0 a 5.<br />

Práctica final (obligatorio): 0 a 2.<br />

Opciones y mejoras <strong>de</strong> <strong>la</strong> práctica final: 0 a 3<br />

Prácticas incrementales: 0 a 1<br />

Ejercicios en foro: 0 a 1<br />

Nota final: Suma <strong>de</strong> notas, mo<strong>de</strong>rada por <strong>la</strong> interpretación <strong>de</strong>l profesor<br />

Mínimo para aprobar:<br />

• aprobado en teoría (2.5) y práctica final (1), y<br />

• 5 puntos <strong>de</strong> nota final<br />

Evaluación teoría: prueba escrita<br />

Evaluación prácticas incrementales (evaluación continua):<br />

entre 0 y 1 (sobre todo <strong>la</strong>s extensiones)<br />

es muy recomendable hacer<strong>la</strong>s<br />

Evaluación práctica final:<br />

posibilidad <strong>de</strong> examen presencial para práctica final<br />

tiene que funcionar en el <strong>la</strong>boratorio<br />

enunciado mínimo obligatorio supone 1, se llega a 2 sólo con calidad y cuidado<br />

en los <strong>de</strong>talles<br />

realización individual <strong>de</strong> <strong>la</strong> práctica<br />

Opciones y mejoras práctica final:<br />

permiten subir <strong>la</strong> nota mucho<br />

Evaluación ejercicios (evaluación continua):<br />

preguntas y ejercicios en foro<br />

Evaluación extraordinaria:<br />

prueba escrita (si no se aprobó <strong>la</strong> ordinaria)<br />

nueva práctica final (si no se aprobó <strong>la</strong> ordinaria)<br />

108


22. Materiales <strong>de</strong> interés para <strong>la</strong> <strong>asignatura</strong><br />

22.1. Material complementario general<br />

Philip Greenspun, Software Engineering for Internet Applications:<br />

http://philip.greenspun.com/seia/<br />

utilizado en un curso <strong>de</strong>l MIT<br />

http://philip.greenspun.com/teaching/one-term-web<br />

22.2. Introducción a Python<br />

http://www.python.org/doc<br />

Documentación en línea <strong>de</strong> Python (incluyendo un Tutorial, los manuales <strong>de</strong><br />

referencia, HOWTOS, etc. Usa <strong>la</strong> versión para Python 2.x<br />

http://www.diveintopython.org/<br />

“Dive into Python”, por Mark Pilgrim. Libro para apren<strong>de</strong>r Python, orientado<br />

a quien ya sabe programa con lenguajes orientados a objetos.<br />

http://wiki.python.org/moin/BeginnersGui<strong>de</strong>/Programmers<br />

Otros textos sobre Python, <strong>de</strong> interés especialmente para quien ya sabe programar<br />

en otros lenguajes.<br />

http://en.wikibooks.org/wiki/Python_Programming<br />

“Python Programming”, Wikibook sobre programación en Python.<br />

http://en.wikipedia.org/wiki/Python_(programming_<strong>la</strong>nguage)<br />

Python en <strong>la</strong> Wikipedia<br />

http://www.python.org/<strong>de</strong>v/peps/pep-0008/<br />

Style Gui<strong>de</strong> for Python Co<strong>de</strong> (PEP 8). Esta es <strong>la</strong> guía <strong>de</strong> estilo que se pue<strong>de</strong><br />

comprobar con el programa pep8.<br />

22.3. Aplicaciones web mínimas<br />

http://docs.python.org/<strong>de</strong>v/howto/sockets.html<br />

“Socket Programming HOWTO”. <strong>Programa</strong>ción <strong>de</strong> sockets en Python, guía<br />

rápida.<br />

http://docs.python.org/library/socket.html<br />

Documentación <strong>de</strong> <strong>la</strong> biblioteca <strong>de</strong> sockets <strong>de</strong> Python.<br />

109


https://addons.mozil<strong>la</strong>.org/en-US/firefox/<br />

Lista <strong>de</strong> add-ons y plugins para Firefox.<br />

22.4. SQL y SQLite<br />

http://www.shokhirev.com/niko<strong>la</strong>i/abc/sql/sql.html<br />

“SQLite / SQL Tutorials: Basic SQL”, por Niko<strong>la</strong>i Shokhirev<br />

110

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!