Guia de Bs As

Home Page
HOME
Blog
Netmarks [external]
Life
NEWS

The Code
pop3filter [external]
slackftp [external]
slackdep
iolsucker
jiolsucker
distcleaner
ftpindex
LICQ patches
--------------
SVN Repository

Articles
Papel Digital
PA 2003

Buenos Aires
Argentina

Pensamientos sobre la version digital de las Páginas Blancas (Amarillas*) de 2003 y sobre otras cosas

por Juan F. Codagnone juam at {arnet.com.ar,users.sourceforge.net}
02 Abril 2003
Revisión 1.1
(*) desconozco si Paginas Amarillas es una marca registrada. Las marcas registradas que se mencionan son propiedad de sus empresas.

0. Índice

  1. Índice
  2. Licencia
  3. Introducción
  4. El producto y sus problemas
  5. Conversiones & filtros
  6. Posibles soluciones
  7. Algunas inusuales consultas sobre los datos
  8. Referencias externas

1. Licencia

Copyright © 2003 por Juan F. Codagnone. Este material puede ser distribuido sólo sujeto a los términos y condiciones explicitados en la Open Publication License v1.0 o posterior (la última se encuentra disponible en http://www.opencontent.org/openpub/[1]), sin hacer uso de las opciones del inciso VI.

2. Introducción

Por estos días (1ero de Abril) se están entregando las guía telefónicas 2003 de la Ciudad Autonoma de Buenos Aires. Al parecer, la empresa encargada de las Páginas Amarillas (Paginas Amarillas del grupo Telecom?), está dando la posibilidad de elegir entre una guía física o un delgado CD-ROM. El presente artículo resalta las cosas buena de dicha entrega, analiza sus problemas, y levanta algunas dudas legales.

3. El producto y sus problemas

El CD que se entrega, viene en una caja de cartón con varias `alas'. En uno de los borde de ésta, se menciona los requisitos del sistema, entre los cuales se encuentra el sistema operativo de las ventanitas. Sin embargo, viendo el contenido del cd, la gente que desarrolló el producto, tuvo en cuenta la portabilidad del mismo. Esto se puede se ver en la documentación que se encuentra en formato HTML, donde se menciona al sistema operativo de la manzanita, y a por lo menos cuatro sabores de U*IX (contando al pinguinito). Ni bien se ingresa al directorio Programa/ se ven archivos swf, los cuales guían al usuario entre las consultas. Es evidente el compromiso por el equipo de desarrollo por hacer algo portable.

Entonces, ¿Dónde está el problema? Nada mejor que la portabilidad! balbuceará el lector atento, que todavía recuerda el título de esta sección. El problema está en que las guías están en formato PDF. Este formato es genial para distribuir trabajos que solo requieren ser leidos por otras personas, y donde el aspecto si interesa. La guía telefónica, además de servir para nivelar patas de muebles, sirve para buscar el número de teléfono de alguna persona, y es en esto donde falla el producto.

De ahora en más, cuando se mencione guía telefónica, el autor se estará refeririendo especificamente a las páginas blancas (en oposición a las páginas amarillas). Las páginas blancas están en el CD como commoditie: la fuente de ingreso para la empresa que arma las guías telefónicas son las páginas amarillas. El cartón que trae el disco compacto, sólo dice páginas amarillas, y describe sus bondades.

Para agilizar un poco la búsqueda, el pdf tiene 27 letras (A-Z y Ñ) como marca de pagina. Las instrucciones de uso dice que para buscar se debe seleccionar la letra con la que inicia el apellido o razón social que se busca , y buscar como en la guía de papel (!!!). Ésto, no tiene en cuenta que realizar una búsqueda binaria con un pequeño cursor en una gran scrollbar no es una tarea tan sencilla como dividir a la mitad un pilón de hojas con la mano.

Una forma alternativa de búsqueda, es con el comando buscar de programa visor de pdf. ¿Qué problemas tiene esta forma de búsqueda? Uno debe acordarse de setear la opción para que la búsqueda machee dependiendo de las mayúsculas, e ingresar el apellido todo en mayúsculas. ¿Cómo advierte que la búsqueda no tuvo ningun éxito? Se llegó al fin del archivo, o pasó un rato largo.

Una feature extra en la versión digital de la guía, se tiene la posibilidad de hacer consultas sobre lo que se suele llamar la guía inversa: dado un telefono, se puede averiguar los datos del propietario. Ésto no es muy novedoso ya que el sitio de internet de las Páginas Amarillas[2] también lo permite.

Otra cosa que no está clara, es que cosas se puede hacer con los datos. En el cartón se lee:

PROHIBIDA LA REPRODUCCION TOTAL O PARCIAL DE ESTA OBRA, SU TRATAMIENTO INFORMATICO, ELECTRONICA, DIGITAL, MECANICO Y/O CUALQUIER OTRO.
En la compilación de datos se alude a Publicom y Telinver SA. ¿Cuál es la licencia de uso del programa y la base? IANAL (no soy un abogado): ¿Estos tipo de datos datos pueden ser protegidos? El autor [Juan] tendría que revisar la Ley 25326[3](Habeas Data), pero jamás le cedió dicha información a esas compañias. Si el lector puede guiar al autor por las respuesta de éstas preguntas, no dude en contactarse con él.

4. Conversiones & filtros

Los problemas mencionados antes, motivaron a escribir algún filtro que conviertiera el pdf a otra especie de datos que facilitara la búsqueda. ¿La utilidad? Ninguna, un desafío más, y demostración de concepto. Toda la información de la guía ya se puede consultar desde internet en forma digital así que no agregaría un nuevo medio.

Debido a las preguntas legales mencionadas con anterioridad, me veo a obligado a declarar que el filtro creado con el fin de ejercer cierto uso justo (fair-use) sobre la obra, y para educación e investigación. Ningun resultado directo del filtro es distribuido. Por otro lado, el filtro nunca accede directamente al pdf (sino que otros programas ajenos al autor lo hacen), por lo que el filtro no se debería ser considerado como un dispositivo de circunvalación[4] de tecnología (por hay, hay un loco con la DMCA[5] leyendo)(¿No se puede considerar el filtro como un poema a AWK? ¿De esa forma quedo protegido por la libertad de expresión? Si una ley me proscribiera de poder escribir estas líneas de codigo, mi expresión estaría inconclusa...esto es mas bien un juego de palabras. Se aceptan sugeriencias para debatir el tema). No se lastimó a ningun pinguino o demonio escribiendo el documento :^).

Antes de mostrar el filtro es importante describir el formato de la guía. Cada registro, tiene un apellido o nombre de razón social que se encuentra todo en letra mayúsculas negrita. Le sigue el primer nombre y todas sus iniciales en letra negrita (este campo puede no existir). A continuación de esto está la dirección seguido por una linea puneada y el teléfono. Tener en cuenta la negrita es vital, si se quiere extaer datos correctos (ej: si Juan Alejandro Perez viviese en la calle F G Lorca entonces el registro seria "PEREZ Juan A F G Lorca"). Esto marca la pauta de que se debe convertir el pdf a un formato con formato rico, o a ASCII con marcas de formato (en los emails y newsgroups se utiliza *palabra* para marcar que palabra está en negrita y _palabra_ para indicar la letra itálica). La opción más simple (sin programación de por medio) fue usar html como formato intermedio usando el programa pdf2html[6].

La salida de pdf2hml cuando se aplica a la guía, es de la forma:

out.dat (209 bytes) Descargar
<A name=3></a><b>Apellido</b><br>
<b>(cont.)</b><br>
<b>» Osvaldo</b><br>
Calle 1234<br>
<b>....................9999-9999</b><br>
<b>» Ramon</b><br>
Calle1 4321<br>
<b>.......................4123-4567</b><br>
Listado 4-1

El filtro está escrito mayoritariamente en AWK[7] (un lenguaje creado en Bell Labs para filtrar y procesar información telefonica), con algunas conversiones de sed y una conexión entre éstos usando bash2. No debe ser tomado como un ejemplo a seguir de estilo. Puede ignorar con seguridad las tres primeras funciones (usage(), version(), y parseOptions()). La idea inicial era armar una máquina de estado finito (varible state) pero al final decidí tomar decisiones en base sólo a la entrada.

guia2ascii.sh (4.19 KB) Descargar
#!/bin/bash
#
# Copyright (C) 2003 by Juan F. Codagnone <juam /@/ arnet com ar>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

VERSION="1.0.0"
first=""
last=""
pdftohtml="../../pdftohtml"
function usage()
{	echo "Usage: $0 [-vh] [-f first_page] [-l last_page] guia.pdf"
	echo
	echo "send suggestions to juam  arnet . com . ar"
}

function version()
{	echo "Version $VERSION" 
	cat << EOF

Copyright (C) 2003 Juan F. Codagnone
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
}

function parseOptions()
{	local opt
	local OPTIND
	local OPTARG
	local OPTERR
	local OPTSTRING
	local t

	while getopts "hvf:l:" opt
	do
		case $opt in
		  h)	usage ; 
			t=$?
			exit  $? ;;
		  v)	version ; 
			t=$?
			exit $?;;
		  f)  	first="-f ${OPTARG}";;
		  l)	last="-l ${OPTARG}";;
		esac
	done

	if [[ -z "$guia" ]]; then
		guia=`eval echo "$"${OPTIND}`
		if [[ -z "$guia" ]]; then
			usage
			exit 1
		fi
	fi
	if [[ ! -a "$guia" ]]; then
		echo "file '$guia' does not exists. aborting"
		exit 1
	fi
}

function main()
{
$pdftohtml $first $last  -stdout $guia |
sed -e  's/»/ @  /g' \
    -e  's/[.]//g'  \
    -e  "s/'/\'/g" \
    -e  's/<br>//g' \
    -e  's/<A name=/<A name= /g' \
    -e  's/><\/a>/ ><\/a> \
/g' |
sed  -e 's/>/> /g' -e 's/</ </g'  |
# remove html headers 
awk '
{
	if( p  )
		print 
	if( $1=="<BODY" )
		p=1;

}' | 
# showtime
awk '

function isBold(str)
{
	return str ~ "^<(/|)(b|B)>$"
}


function istelnum(str)
{
	return str ~ "^[[:digit:]]*-[[:digit:]]*$"
}

function isupper(str)
{
	return  !istelnum(str) && str==toupper(str)
}

function printreg()
{
	if( surname=="" || street=="" || streetnum=="" || tel=="" )
	{	print "ERROR " page "|" surname "|" name "|" street "|" \
		      streetnum "|" tel >> "errors"
		fflush("errors")
	}
	else
	{	l = substr(surname,0,1)
		if( file=="" ||  l != file  )
			printf("") > l
		file=l
		print page "|" surname "|" name "|" street "|" streetnum "|" \
		      tel >> file
	}
	lastsurname=surname
	surname=""
	name=""
	tel=""
	street=""
	streetnum=""
	nr++;
}

# ignore html trailing headers
$0 ~ "^[[:space:]]*</(HTML|BODY)>[[:space:]]*$" { next ; }


BEGIN {
	print "" > "errors"
	nr=0
}
END {
	printreg()
	print "Page " page ": " nr - lastnr   " records(total " nr ")"   
}
# detect a new page 
$0 ~ "^[[:space:]]*[<]A name=" { 
	page=$3 
	if( page-1 != 0 )
		print "Page " page-1 ": " nr - lastnr   " records(total " nr ")"   
	lastnr=nr
	next 
}

# ignore cover 
page == 1 { next } 

# else
{	
	if ( $0~"^ <b> [[:alpha:]]+-[[:alpha:]]+[[:space:]]*</b>[[:space:]]*$" )
	{	getline;
		getline;
	}
	else if( isBold($1) && istelnum($2) && isBold($3) )
	{	tel=$2
		state = 0;
		printreg()
	}
	else if( isBold($1) && $2=="@" )
	{	if( surname == "" )
			surname=lastsurname
		for(i=3; i<NF ; i++ )	
		{	if( name=="" )
				name=$i
			else
				name=sprintf("%s %s",name,$i);
		}
		state=2
	}
	else if ( !isBold($1) && !isBold($NF) )
	{
		for( i=1; i < NF ; i++ )
		{	if( street=="" )
				street=$i
			else
				street=sprintf("%s %s",street,$i);
		}
		streetnum=$NF
	}
	else if( state==0 )
	{	if( isBold($1) && isBold($NF) && isupper($2) )
		{	lastsurname=surname
			name=""
			surname=""
			tel=""
			for( i=2 ; i<NF && isupper($i) ; i++ )
			{	if( surname=="" )
					surname=$i
				else
					surname=sprintf("%s %s",surname, $i);
			}
			if( surname=="" )
				surname=lastsurname;
				
			if( i != NF )
			{	for( ; i<NF ; i++ )
				{	if( name=="" )
						name=$i;
					else
						name=sprintf("%s %s",name,$i);
				}
				state=2
			}
			else
				state = 1;
		}
	}
}'
}

parseOptions $*
main
Listado 4-2

De probar el filtro, seguramente obtendrá el mensaje:

Error: Copying of text from this document is not allowed.
Esto se debe a que el documento tiene los bits de ``seguridad'' prendidos. En este caso en particular, se permite imprimir el archivo, pero no copiar texto o imágenes. Ésto hace recordar bastante al caso DVD-Jon[8] en el cual los consumidores no podían ver el dvd que habían comprado para mirar, en la reproductora de dvd que también habian comprado, pero con un programa libre.

Quien haya pasado un tiempo eligiendo impresoras para comprar, sabe que existen dos grandes tipos de impresoras en el mercado: las que hablan PostScript (PS de ahora en más) y las que hablan PCL. Un PDF es muy similar a un PS. Si el usuario instala los drivers de una impresora PS, e imprime a un archivo el PDF obtiene un PS con su contenido. Uno de los objetivos que se persiguió fue intentar no modificar ninguna línea de otro programa. Antes de usar pdf2html la idea fue trabajar sobre el PS que era generado en la impresión. El problema fue que tanto programas como pstotext y ps2ascii se comían espacios (de diferentes formas), complicando el filtro. El autor no recuerda porqué no utilizó ps2html.

Como último recurso, se decidió utilizar pdftohtml. Este programa honra los bits de seguridad, por lo que se procedió a comentar la linea (un goto!) que imprimía el mensaje de error y terminaba el programa. El autor comparte la posición del autor del programa XPDF[9](pdftohtml se basa en código del XPDF) sobre honrar los bits de seguridad: éste es un caso especial.

Por último, y en forma de anecdota, me sorprendió ver en el codigo PS generado por el visor de PDFs de Acrobat® del sistema del pinguinito (y no en el PS generado para el driver de la impresora o ps2pdf) el comentario:

dmca.txt (670 bytes) Descargar
% Removing the following eight lines is illegal, subject to the Digital 
% Copyright Act of 1998.
mark currentfile eexec
54dc5232e897cbaaa7584b7da7c23a6c59e7451851159cdbf40334cc2600
30036a856fabb196b3ddab71514d79106c969797b119ae4379c5ac9b7318
33471fc81a8e4b87bac59f7003cddaebea2a741c4e80818b4b136660994b
18a85d6b60e3c6b57cc0815fe834bc82704ac2caf0b6e228ce1b2218c8c7
67e87aef6db14cd38dda844c855b4e9c46d510cab8fdaa521d67cbb83ee1
af966cc79653b9aca2a5f91f908bbd3f06ecc0c940097ec77e210e6184dc
2f5777aacfc6907d43f1edb490a2a89c9af5b90ff126c0c3c5da9ae99f59
d47040be1c0336205bf3c6169b1b01cd78f922ec384cd0fcab955c0c20de
000000000000000000000000000000000000000000000000000000000000
Listado 4-3

5. Posibles soluciones

Agregar al CD, un programa de búsqueda portable (el pdf igual es lindo tenerlo en el cd). El autor, no sabe si desde un swf se puede manejar archivos o si hay alguna función del estilo la libdb. Otra solución que funcionaría out of the box sería usar el gigante Java, o algun lenguaje interpretado como TCL o Python. También, se podría armar en C, C++ (se pueden armar con esfuerzo mínimo interfases gráficas portables usando GTK, QT, o wxWindows), pero esto ya no funcionaría out of the box porque requeriría diferentes versiones compiladas.

6. Algunas inusuales consultas sobre los datos

Algunas consultas que nunca se imaginó llegar a poder hacer. No se tuvo tiempo de instalar un DBMS para realizar consultas SQL, por lo que los números que se presentan están sacados con consultas que usan AWK y sort.

En total, en la Ciudad de Buenos Aires, hay 1.084.632 teléfonos registrados en la guía, 2.761 calles registradas diferentes, y 166.259 apellidos diferentes.

Existen alrededor de 41.000 hogares con 2 o más líneas telefónicas (criterio: mismo apellido, nombre, y direccion, diferente teléfono). La caja del cd menciona que se crearon 22.000 ejemplares. Claramente se apostó a que la mitad de estos hogares cambiarían una de las guías físicas por el cd.

En las siguientes consultas sólo se muestra las primeras entradas de la tabla. Puede descargar la tabla completa en un formato con separadores.

  • ¿Cuales son los apellidos más comunes?
  • ¿Que calles tienen mayor cantidad de telefonos?
  • ¿Cuales son los primeros nombres más comunes?
  • Cantidad de teléfonos por carácteristica
  • 11509 FERNANDEZ
    10706 RODRIGUEZ
    9749 GONZALEZ
    8514 GARCIA
    8384 LOPEZ
    6411 MARTINEZ
    6379 PEREZ
    5012 ALVAREZ
    4808 GOMEZ
    4622 SANCHEZ
    4466 DIAZ
    Tabla 6-1 Descargar completa (9.97 KB)
    15085 Av Rivadavia
    10791 Av Santa Fe
    9121 Av Corrientes
    8114 Av Libertador
    7930 Paraguay
    6935 Arenales
    6872 Juncal
    6860 Av Córdoba
    5823 Billinghurst
    5658 Av J B Alberdi
    5633 Sarmiento
    Tabla 6-2 Descargar completa (41.56 KB)
    56796 Maria
    55249 María
    23518 Juan
    22679 Carlos
    21495 Ana
    19884 Jorge
    14931 Marta
    14468 Susana
    13248 Alicia
    13097 Rosa
    12362 De
    Tabla 6-3 Descargar completa (6.45 KB)
    8669 4642
    8629 4432
    8545 4672
    8502 4671
    8480 4431
    8462 4567
    8413 4566
    8360 4568
    8324 4503
    8306 4902
    8305 4631
    Tabla 6-4 Descargar completa (2.17 KB)

    Para la tabla 2 también sería más representativo averiguar la densidad de telefonos por calle (altura de calle mayor-altura de calle menor?).

    En la tabla 3 se ve como primer nombre la palabra "De". Sin duda hay que volver a correr la consulta buscando la palabra siguiente a De.

    7. Referencias externas

    1. http://www.opencontent.org/openpub/
      Open Publication License
    2. http://paginasamarillas.com.ar/
      Sitio de internet de las páginas amarillas
    3. http://www.anticorrupcion.jus.gov.ar/ley25326.pdf
      Ley 25326
    4. http://www.freedom-to-tinker.com/archives/cat_fritzs_hit_list.html
      Freedom to Tinker ... is your freedom to understand, discuss, repair, and modify the technological devices you own.
    5. http://anti-dmca.org/
      DMCA
    6. http://pdftohtml.sourceforge.net/
      Sitio del programa pdf2html
    7. http://cm.bell-labs.com/cm/cs/awkbook/
      AWK
    8. http://www.eff.org/IP/Video/MPAA_DVD_cases/
      Casos sobre MPAA-DVD
    9. http://www.foolabs.com/xpdf/cracking.html
      Comentarios del autor de XPDF sobre las opciones de seguridad del pdf

    Generated on Sat, 11 Feb 2006 21:18:56 -0300