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
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