Language programming books, photo by Helder da Rocha

Clases, Objetos e Instancias

Download PDF

Abrimos el mes de julio con mucho trabajo y hemos estado lentos en la publicación por este vuestro humilde «web log» pero hicimos un paréntesis con la simple traducción de un artículo duro y contundente a propósito de un trabajo de investigación que venimos desarrollando. Estos conceptos -expuestos de una manera muy práctica y orientados sobre lenguaje Java- los consideramos fundamentales (a pesar que algunos programadores han anunciado este modelo como en decadencia) por ello los traducimos tal cual y además les agregamos unos enlaces para que veaís cuán profundo es el tema y como de maravilloso lo simplificaron en el artículo que citamos en idioma castellano a continuación.

Language programming books, photo by Helder da Rocha
Language programming books, photo by Helder da Rocha /147570929

Clase versus Objeto versus Instancia

En la Programación Orientada a Objeto frecuentemente escuchamos términos como «Clase», «Objeto» e «Instancia» pero ¿qué es una Clase / Objeto / Instancia en realidad?

En resumen, un objeto es un paquete de software de estado y comportamiento relacionados. Una Clase es un modelo o prototipo del que se crean los Objetos. Una Instancia es una sencilla y singular unidad de una clase.

Por ejemplo, tenemos un proyecto (Clase) que representa al «Estudiante» (Objeto) con campos como nombre, edad, curso (miembro de la Clase). Y tenemos dos estudiantes aquí, José y María. Así, José y María son dos Instancias diferentes de la clase «Estudiante» que representan el Objeto (personas Estudiantes). Veamos mayores detalles.

Objeto.

Los objetos del mundo real comparten 2 características principales, estado y comportamiento. Los humanos tienen estado (nombre, edad) y comportamiento (correr, dormir). Los objetos de software son conceptualmente similares a los objetos del mundo real: ellos también consisten en el estado y el comportamiento relacionado. Un Objeto almacena su estado en campos y expone su comportamiento a través de métodos.

Clase.

La clase es una «plantilla» o «modelo» que se utiliza para crear objetos. Básicamente, una clase consistirá en campo, campo estático, método, método estático y constructor. Campo se utiliza para mantener el estado de la clase (por ejemplo: nombre del objeto Estudiante). El método se utiliza para representar el comportamiento de la clase (por ejemplo: cómo un objeto Estudiante va a ponerse de pie). Constructor se utiliza para crear una nueva instancia de la clase.

Instancia.

Una Instancia es una copia única de una clase que representa un Objeto. Cuando se crea una nueva Instancia de una Clase, el ordenador asignará un espacio de memoria para esa Instancia de Clase (en nuestro ejemplo, José y María tendrán su espacio aparte e independientes en memoria).

Nota: aunque no está en el artículo original, quisieramos agregar algo adicional con respecto a las Instancias, y es que pudiera darse el caso que se pudieran compartir los valores de campo fácilmente entre dos o más Instancias y precisamente eso es lo que facilita la programación. Si la Clase Estudiante tiene un campo llamado «residencia» (la cual tiene subcampos que contienen la dirección de habitación – estado, ciudad, barrio, calle, casa, etc.- de José y María) y ellos son parejas y viven en la misma casa pues con solo rellenar los campos de María al finalizar los «igualamos» -copiamos- en un solo paso a la Instancia Pedro ¡fácil!.

Fuentes consultadas.

En idioma castellano.

En idioma inglés.

Download PDF
Impuesto Sobre La Renta (ISLR)

ISLR retenciones

Download PDF

El pasado 12 de mayo se cumplieron 20 años del Decreto Presidencial 1.808 el cual dicta las normas y procedimientos para las retenciones del Impuesto Sobre La Renta (ISLR). En todo ese tiempo hemos tenido dos Constituciones (enmienda incluida), varios Presidentes de la República, Congreso de Diputados y Senadores y luego una Asamblea Nacional Legislativa e infinidad de Ministros y Ministras ¿Cómo es posible que este decreto haya sobrevivido tanto tiempo?

Advertencia.
Advertencia.

Por supuesto que este artículo está dirigido a los venezolanos y venezolanas que hace muchísimos años nos retienen el Impuesto Sobre La Renta  «ISLR» en nuestro trabajo intelectual de servicios a las empresas privadas (nunca hemos laborado ni contratado con el sector público). No somos licenciados, ni contadores, mucho menos abogados, pero ya saben como reza el dicho «se puede desconocer la Ley pero la Ley no lo desconoce a usted» Y POR ESO ES MEJOR ESTUDIAR LA LEGISLACIÓN AL RESPECTO ya que estamos directamente involucrados. Vamos pues a este proceso de aprendizaje (o redescubrimiento, en realidad) de las Ciencias Sociales, rama Tributaria.

Impuesto Sobre La Renta (ISLR)
Impuesto Sobre La Renta (ISLR)

Seguir leyendo

Download PDF

Marp a primera vista

Download PDF

Nos empeñamos en realizar tutoriales pero en este caso vamos a realizar una simple revisión a un software novísimo: Marp. Esta entrada viene a colación por un «tuit» del sr. Aitor León desde Sevilla, España donde hace un autorecordatorio sobre un software del cual nosotros no habíamos escuchado antes y que nos llamó la atención porque le aplicó la etiqueta #MarkDown:

Nosotros con mucho respeto le preguntamos qué era ese programa y amablemente nos respondió:

Ni tardo ni perezosos indagamos y he aquí lo que pudimos aprender, lo cual humildemente compartimos con el mundo entero de habla castellana.

Inicio y desarrollo de Marp.

Un paso para comenzar.

Ya bien dice el refrán que todo viaje, por muy largo que sea, comienza con un solo paso: el 11 de febrero de 2016 (hace una gran cantidad de tiempo en términos de ordenador japonés) se escribió el comienzo de Marp, el cual originalmente se llamaba MDSlide en su versión 0.0.1.

[cc lang=»javascript» tab_size=»2″ lines=»40″]
{
«name»: «mdslide»,
– «version»: «0.0.0»,
+ «version»: «0.0.1»,
«description»: «Presentation writer with markdown»,
«main»: «main.js»,
«scripts»: {
[/cc]

Desarrollo: nace Marp.

En mayo de 2016, luego de duro trabajo, MDSlide se transforma en Marp y la numeración de versiones correlativo corresponde a V0.0.6; al cambiar de nombre nace un repositorio nuevo y de MDSlide no quedan rastros… dice uno porque bien sabemos que el protocolo Git es distribuido y por ahí en algún disco fijo debe haber una copia, je, je, je. El logotipo es el ahora conocido y la verdad ya estaba bastante maduro: soporte para emoji, ecuaciones matemáticas (eso nos impresiona) e imágenes (recordad que se basa en MarkDown: se trabaja con teclado).

Ruta de trabajo.

Para octubre de 2016 se retoma el desarrollo debido a que escuchando las sugerencias de los usuarios se replantea todo y liberan la versión 0.0.9 y se declara un plan de trabajo para liberar la tan ansiada versión 1.0 . También debemos tomar en cuenta que Electron, el entorno de programación utilizado, también ha sido actualizado y eso «empuja» a Marp en cierta medida y a pesar de suficientes «pull requests» (copias del código fuente modificado por terceros que lo devuelven mejorado y/o con sugencias) que recibe el sr. Hattori, él ratifica que sigue en las riendas del proyecto y espera mejorarlo mucho gracias a sus usuarios y colaboradores. Pero en este punto reconoce que el modo de presentación es la parte más difícil y es algo que aún no han logrado pulir, pues es esa la característica que estuvimos buscando nosotros y no vemos por ningún lado (más adelante mostraremos su uso con ejemplos en castellano). La «discusión» es viva y candente (en inglés) e incluso se le llega a comparar con software privativo que lleva décadas en el mercado.

Última versión a la fecha de escribir este artículo.

En noviembre de 2016 liberan la versión 0.0.1 que es la versión que descargamos y probamos pero al abrirlo nos encontramos con una versión compilada a lenguaje de máquina y con una extraña versión 1.3.8 ¿En qué momento nos perdimos… de algo? De todos modos no especulemos nada aún, en la parte del licenciamiento veremos bien si realmente es «software libre» o de «fuente abierta».

Autoría.

Así nació Marp de las manos del Ingeniero de Software Web Yuki Hattori, graduado en « 公立はこだて未来大学 » («Public Hakodate Future University») y quien actualmente trabaja en la empresa «Speee, Inc.» en Tokio, Japón.

Ingeniero Yuki Hattori
Ingeniero Yuki Hattori

El Ingeniero Hattori maneja una gran cantidad de lenguajes de programación (vamos que desayuna PHP, merienda con CSS, almuerza con Ruby, la merienda de la tarde la pasa con Node y cena con Rails) y nosotros que pensábamos que algo programamos, pues nos quedamos cortos (44% en otros lenguajes de programación ¿cuáles serán? Acá hace algo con SVG dinámico y en este enlace lo podéis probar y modificar cortesía de Phil Maurer).

Yuki Hattori lenguajes de programación más utilizados
Yuki Hattori lenguajes de programación más utilizados

Licencia de uso.

El repositorio oficial de Marp lo podéis encontrar en este enlace, y de sus múltiples secciones hemos leído y analizado la información para el presente artículo, esparamos os sea útil en algún modo.

En junio de 2016 el proyecto tiene un mes con su nombre actual Marp y deciden colocar correctamente la licencia de uso que corresponde a la del Instituto Tecnológico de Massachusetts (MIT) la cual no puede ser un simple enlace web, se debe colocar el encabezado con el año y el nombre del autor para luego copiar fielmente la licencia de uso del MIT y luego, si se quiere, el enlace web correspondiente.

De hecho múltiples organismos conservan una copia de dicha licencia y la más socorrida es la de «The Open Source Initiative»; vale la pena recordar entonces que una cosa es software libre y otra cosa es código fuente abierto: para no ser puristas el software libre es más antiguo y solo tiene 4 reglas básicas (aunque ha evolucionado) y el código fuente abierto deriva su filosofía del software libre y tiene 10 reglas básicas.

En julio de 2016 se reconoce que el proyecto contiene un trabajo realizado con anterioridad y que también posee licencia de uso del MIT: Katex el cual está escrito en JavaScript y CSS para representar gráficamente las tediosas fórmulas matemáticas. Nosotros que estudiamos ingeniería mecánica y nos tocó estudiar matemáticas avanzadas damos fe del tremendo trabajo de presentar informes y no tener un software adecuado para ello. Da un poco de vergüenza decirlo pero era rapídisimo realizarlo de forma manuscrita y presentable en hojas blancas que lo horroroso que quedaban con las impresoras de matríz de punto y el software que disponíamos. Hemos progresado hasta el punto que hoy tenemos presentaciones en un lenguaje de marcación ligero y sencillo, que puede representar las matemáticas como son ¡y de paso se puede exportar a formato pdf, increíble!

En este mismo mes se decide retirar el anuncio de licencia de uso de underscore.js ya que no se sigue utilizando como componente.

Página web oficial de Marp.

En este enlace se tiene una presentación bien cuidada acerca del software y orientada a los usuarios normales, no programadores. Podemos ver su características, un enlace al repositorio, un enlace para descargarlo, una rápida introducción a su uso, una guía a ejemplos más avanzados y una declaratoria de licencia de uso. Lo que nos llama poderosamente nuestra atención es la inserción de dos objetos web que presentan por diapositivas a Marp, dichos objetos fueron hechos en Deckset -software hecho en Alemania-el cual está también basado en MarkDown… ¿casualidad? Bueno acá el software de fuente abierta supera al privativo, pues no exporta en formato pdf… y podremos agregarle funcionalidades que consideremos haciendole un «fork» y haciendo nuestro propio proyecto (conservando la licencia de uso del MIT, por supuesto).

«Instalando» Marp.

Pues que si llamamos «instalar» a descargar un archivo y descomprimirlo, vale, «cuela» como instalación. Esta entrada no es tan compleja como otras que hemos hecho que analizamos lo más a fondo que podemos su código fuente, pero no os preocupéis, no perderemos de vista a Marp en el futuro. Repetimos, el repositorio está en esta dirección.

Usando Marp.

Pilares fundamentales de Marp.

  • Escribimos en MarkDown las presentaciones (y también podemos ver el resultado del MarkDown).
  • Se pueden escoger temas y fondos de pantalla para las presentaciones.
  • Soporta caracteres UNICODE (mejor conocidos como emojis).
  • Se puden escribir ecuaciones matemáticas con hermoso estilo.
  • Se puede exportar a formato PDF.

Haciendo presentaciones en MarkDown.

Retrospectiva.

Admitámoslo: realizar presentaciones es tedioso para los que no tenemos el talento para los gráficos. Somos empedernidos usuarios de la ventana terminal y por eso nos agrada mucho el MarkDown y su simple sintaxis para obetener una apariencia básica del HTML… ¡Pero esperen, hay más!

Desde que Github popularizara el Git con su alojamiento gratuito para proyectos públicos (que de acuerdo a la licencia de uso que tengan tendrán diferentes clasificaciones) y agregaron el uso de MarkDown acompañando a los repositorios con su respectiva sección Wiki, que también utiliza cierto «sabor» de MarkDown, y ahora con una ligera variante podremos hacer presentaciones rápidamente sobre nuestro trabajo ya hecho pues… ¡BINGO! ??

Hala, manos a la obra.

Aunque entre las carpetas descomprimidas hay una llamada «locales» hay un archivo llamado es.pak cuyo contenido abrimos con gedit y está escrito en castellano, no hallamos opción para cambiar el idioma inglés. Revisando el código fuente no hallamos referencia a dichos archivos .pak (hay bastantes idiomas) lo que imaginamos es que son «paquetes»  o plantillas que se utilizan masivamente para internacionalizar nuestras aplicaciones… o simplemente será nuestra imaginación.

Dicho todo esto, os escribiremos en inglés las referencias que hagamos al programa Marp.

No nos afanéis buscando teclas de acceso directo -para hacer cualquier cosa- excepto las siguientes:

CTRL+NNew fileFichero nuevo
CTRL+OOpen...Abrir un fichero
CTRL+SSaveGuardar fichero
Mayús+CTRL+EExport slides as PDFExportar presentaciones a formato PDF
CTRL+WCloseCerrar programa
CTRL+ZUndoDeshacer acción
Mayús+CTRL+ZRedoRehacer acción
CTRL+XCutCortar selección
CTRL+CCopyCopiar selección
CTRL+VPastePegar selección
CTRL+ASelect allSeleccionar todo
F11Toggle full screenCambiar a pantalla completa

Marp, como es de esperarse, utiliza la misma extensión de fichero de los documentos MarkDown: .md (tal vez presentemos algún vahído porque estamos bien acostumbrados a que las presentaciones tienen sus propias extensiones según el software que las manipule).

Lo primero es abrir un archivo nuevo, vamos al menú desplegable «File» -> «New file» (o pulsamos las teclas CTRL+N). Sin más preámbulo se abre un «lienzo» de trabajo presto a escribir en el. En este lienzo a la izquierda escribimos nuestro código y a la derecha veremos inmediatamente nuestro trabajo de tres maneras distintas:

  • En modo de presentación, diapositiva por diapositiva (modo por defecto).
  • En modo de presentación, diapositivas en hilo o «carrousel».
  • En modo MarkDown, tal como se vería al publicarla en la página web de GitHub, por ejemplo (¡interesante!).

Títulos y subtítulos.

Inician con un símbolo numeral «#» seguido de un espacio y el texto para título principal y agregando dos o más numerales juntos -sin espacios- los subtítulos correspondientes (hasta un máximo de seis subniveles):

Marp títulos y subtítulos.
Marp títulos y subtítulos.

Nota 1: Marp como buen intérprete del MarkDown «original» soporta el uso de «=» y «-» (uno o más) en la línea inmediatamente inferior del texto para mostrar un encabezado de primer y segundo nivel. Pero si necesitamos de un  tercer nivel necesitaremos tres numerales «###»… así que no vale la pena este método os aseguro.

Nota 2: Marp aplica a las imágenes un «realzamiento» su utilizamos numeral (es) delante de la declaración de imágenes, sin embargo «=» y «-» no funcionan en estos casos (no le busquen lógica a esto, por favor, no sabemos si es un «bug» o es algo hecho a propósito).

Realizando una segunda diapositiva.

Como véis el código MarkDown funciona y no es obejtivo de esta entrada mostraros su sintaxis por lo tanto vamos a enfocarnos en los comandos propios de Marp, que son apartes del MarkDown con el propósito de presentar nuestras diapositivas.

Tal como insertamos una línea horizontal en Markdown (tres guiones seguidos al principio de una línea) así agregaremos una segunda diapositiva, cuidando de dejar una línea en blanco antes y después:

Marp inserción de nueva diapositiva
Marp inserción de nueva diapositiva

Enumerando las diapositivas.

Para agregar el número de diapositiva en la esquina inferior derecha solo debemos agregar el siguiente código.

<!-- page_number: true -->

A partir de la diapositiva donde insertemos la orden serán numeradas hasta el final, si queremos que todas están numeradas la posicionaremos en la primera diapositiva; por el contrario, si queremos que una diapositiva en particular NO sea numerada modificaremos la directiva anterior agregandole un asterisco para indicar que se le aplique solo a esa diapositiva. Por supuesto, usaremos el valor verdadero o falso a nuestro gusto o necesidad.

Marp numeración de diapositivas
Marp numeración de diapositivas

Directivas globales y directivas locales.

Lo que acabáis de ver «encerradas» entre comentarios tipo HTML «<!— comentario —>» por supuesto no se visualizan en nigún navegador o intérprete de MarkDown sin embargo Marp obtiene sus instrucciones de allí en el formato de una instrucción por línea separadas por dos puntos «:». Dichas instrucciones son llamadas directivas y como vimos serán globales -para todas las diapositivas, el documento completo- o solo para la diapositiva donde se encuentre la directiva que establezcamos siempre y cuando sean antecedidas por un asterisco.

Dado el caso que nos equivoquemos en la sintaxis pues simplemente Marp no las toma en cuenta ni ejecuta y no arroja ningún tipo de mensaje de excepción.

Directiva «$theme» y «template».

Marp soporta plantillas predeterminadas para nosotros dedicarnos a lo valioso de escribir los datos en las diapositivas, lo demás son «adornos de repostería». Al momento de escribir esto estaba disponible el tema gaia y de manera adicional con la directiva template:invert se tiene una inversión en los colores. Esto queda guardado en el documento de diapositivas para que Marp automáticamente la muestre al volver abrir el documento. Nota: si por el menú desplegable escogemos «View»->»Theme»->»default» -o cualquier otro tema que haya disponible- Marp obviará la directiva que hayamos establecida dentro de la diapositiva y mostrará la que le hayamos ordenado. Verbigracia:

Marp directiva theme y template
Marp directiva theme y template

Marp directiva «footer».

Con esta directiva podremos establecer una frase en pie de página ya sea en todas las diapositivas o solo en la que le coloquemos la directiva, recordad el asterisco hace a la directiva local, mirad:

Marp directiva footer
Marp directiva footer

Directiva $size

Esta directiva puede ser confusa porque se refiere a tamaño sin embargo presenta también unos valores que indican proporción pero si buscamos la lógica ambas son excluyentes mutuas y explicamos por qué: todo depende si nuestra presentación será por pantalla (primera opción para el 99% de los casos, vamos que hablamos de presentaciones por diapositivas). El otro asunto es si necesitamos imprimir dichas presentaciones.

  • Para la proporción tenemos «4:3» predeterminado para monitores normales y la mayoría de proyectores traen este valor por defecto y «16:9» para monitores «multimedia» -llamados así porque las películas son grabadas en esa proporción panorámica-.
  • Para el tamaño  de papel tenemos desde A0 hasta A8 y B0 hasta B8, os adelantamos que el «tamaño carta» viene a ser A4 (mirad abajo en las fuentes consultadas el resto de los medidas de papel).
  • Por los dos puntos anteriores es que decimos que son mutuamente excluyentes.
  • Esta directiva solamente es global, recomendamos declararla al principio para un orden efectivo (hicimos pruebas y el asterisco lo que hace es inutlizarla).
  • Es indiferente que usemos mayúsculas o minúsculas en los tamaños de papel.
  • Marp lee de izquierda a derecha y el primer tamaño válido de papel o proporción lo aplica, el resto de los caracteres lo desecha (debería NO aplicar el formato o al menos indicar la excepción, pensamos).
  • No conseguimos hacer funcionar el prefijo documentado «-portrait», recordad que aún es un software en desarrollo y sus gazapos tendrá.
Marp directiva $size
Marp directiva $size

Directivas $width y $height.

De necesitar un tamaño personalizado de papel, estas dos directivas son las adecuadas al caso y ambas heredan todo de la directiva $size por ello no os ponemos gif animado aunque si os podemos decir que si que funciona (¡vamos, animaros a descargar y probar Marp!) y las opciones disponibles son:

  • px: píxeles por defecto, no es necesario colocarle «px».
  • Por la razón anterior las siguientes unidades debéis colocarla juntitas sin espacio(o)s o si no lo interpretará como píxeles.
  • cm: centímetros.
  • mm: milímetros.
  • in: pulgadas «inches».
  • pt: puntos.
  • pc: picas.

En realidad dichas unidades son las utilizadas por CSS excepto em (tamaño de fuente) y «%»; abajo en «Fuentes consultadas» (en idioma portugués) tenéis un enlace si queréis aprender más por vuestra cuenta.

Directiva «$prerender».

Antes de entrar de lleno con las imágenes os presentamos esta directiva especialmente hecha para indicarle a Marp que haga un preproceso de las imágenes de fondo en el caso de que éstas sean muy grandes, aligera el proceso con una carga previa de datos.

<!– prerender: true –>

Comando para mostrar imágenes.

Así como lo leeís, ya finalizamos las directivas y volvemos a los comandos de MarkDown en este caso os indicamos lo siguiente:

  • Para comenzar a insertar una imagen comenza por una línea en blanco donde colocareís ![]( «») tal cual, incluyendo los paréntesis, son 8 caracteres en total.
  • Dentro de los corchetes rectos (paréntesis rectos) colocaréis el texto alterno si no se puede cargar la imagen, podéis dejarlo vacío pero el uso de los corchetes es obligatorio, de lo contrario no muestra imagen alguna.
  • Dentro de los paréntesis (curvos) pero fuera de las comillas dobles el nombre del fichero de la imagen (si reside en la misma carpeta de donde ejecutásteis Marp o una URL válida, local o internet).
  • La razón de utilizar una imagen desde internet es para mostrar los últimos valores o cifras relacionados con el tema de la presentación, de lo contrario llevad tus imágenes junto con el documento Marp
  • Entre la URL de la imagen y las comillas dobles debéis dejar un espacio -el mismo que consideramos al principio en el conjunto de 8 caracteres iniciales de declaración.
  • Dentro de las comillas dobles -que sí son opcionales- podemos colocar una breve descripción acerca de la imagen o una frase nemotécnica que podramos visualizar al pasar el puntero por encima de la imágen, tras lo cual al cabo de menos de un segundo se colocará una pequeña ventanita en blanco sobre negro con el texto que coloquemos.
Comando para mostrar imágenes de fondo.

Muchas personas querrán, en vez de utilizar o crear tema alguno, simplemente fijar una o más imágenes como fondo en las presentaciones. He aquí que Marp se toma la ligera licencia de tomar la sintaxis de las imágenes -en MarkDown– con la excepción que en los corchetes rectos colocamos el comando [bg]  y por supuesto la URL local o remota de la imagen en sí. Dentro de los corchetes rectos acompañando a «bg» más un espacio podemos colocar un procentaje para redimensionar la imagen e incluso podemos colcoar varias imágenes siempre y cuando los porcentajes sumen 100% para garantizar visibilidad completa de cada imagen. El comando «bg» no soporta mayúsculas, disfrutad nuestras pruebas:

Marp fondo de diapositiva
Marp fondo de diapositiva
Comandos para mostrar caracteres emoji.

Si se sorprenden por haber colocado los emoji como subsección de las imágenes preparaos a recibir una historia bien larga… vamos a tratar de resumirla lo mejor posible.

Por allá en los años ochenta cuando nosotros comenzamos a manipular computadoras y luego entramos a estudiar en la Universidad de Carabobo… ¡EA, ¿PARA DÓNDE VAÍS, QUEDAROS Y ESCUCHAD! ?

…? os contábamos que apenas teníamos computadoras de 16 bits XT y luego vinieron las de 32 bits -286, 386, etc- y en los años 90 se populariza -y hay hardware para manejarlo- el UNICODE que no es más que la representación codificada y gráfica -dibujada con papel y lápiz- de unos 65 mil y pico de caracteres- de la mayor parte de los alfabetos ideados por la humanidad. Allí se tuvo previsión de crear unos símbolos que representaban caras con diferentes estados de ánimo y objetos comunes, el gran problema era dibujarlos por pantalla Y ESO AÚN HOY EN DÍA ES DIFÍCIL DE HACERLO ¿por qué decimos esto?

Está bien, los sistemas operativos modernos manejan los códigos extendidos de UNICODE, con tan «poderosos» aparatos que tenemos faltaba más, faltaba menos. Pero a nivel de hardware, de tarjeta madre, aún no hemos visto que tengan dicho UNICODE grabado en firmware, los asiáticos han hecho hermosos BIOS gráficos pero que en realidad lo que hacen es cargar en memoria un mini sistema operativo con interfaz gráfica para su idiomas basados en ideogramas: AÚN NO SUCEDE QUE EL CPU ENVIE A UN MONITOR CUALQUIERA EL CÓDIGO BINARIO DE UN CARACTER UNICODE (EXTENDIDO) Y EL MONITOR TENGA «MEMORIA» PARA SABER COMO SE DIBUJA ¿Nos seguís el hilo? {Nota: todo monitor e impresora de matriz de puntos tiene en memoria cómo dibujar los 255 caracteres ASCII originales, pero hasta allí llegan, e incluso las impresoras a inyección de tinta y láser ¡perdieron esa capacidad!}.

Más aún, la genialidad de Steve Jobs, el fundador de Apple Computer -hoy la empresa más poderosa del mundo, incluso por encima de Microsoft e IBM juntas- fue el poner en práctica el trabajo desarrollado por Xerox Palo Alto (empresa aliada mutua con Apple) de fuentes tipográficas: pequeñísimas imágenes que computadoras con la suficiente potencia pueden dibujar rápidamente en pantalla imágenes que nosotros identificamos como «letras»… ¿y todo este discurso para qué? ?

Todo este discurso es para deciros que aún los sistemas operativos modernos NO POSEEN soporte nativo y por ende los navegadores web tienen que obtener de algún lado esas pequeñísimas imágenes que nosotros lamamos «letras» o,  para este caso, emoticons.

Repetimos, lo simplificamos lo más que pudimos, en serio, no somos licenciados en computación pero como nos tocó vivir esa experiencia en carne propia, la evolución de los ordenadores (y escribimos, que algo queda para la posteridad de las generacioens futuras) pero a ese nivel da este tema.

Volviendo al tema de los emoticons o emoticones para castellanizar el término, revisamos el código fuente de Marp y observamos que utiliza dentro de sus dependencias (a esto nosotros lo llamamos librerías dinámicas) algo llamado «markdown-it-emoji» y a su vez buscamos en el código fuente de ese software unos «comandos» que permitan especificar los emoji en Marp.

Para Marp un emoticon o emoji viene encerrado entre par de dos puntos «: :» y dentro, sin espacios viene la palabra clave con la cual se busca y se dibuja (imaginamos que al compilar Marp todas esas imágenes vienen a nuestro disco duro en el fichero ejecutable luego investigamos y nos dimos cuenta que a este proceso ELECTRON lo llama «Application Distribution«, con el archivo app.asar del cual podrán saber y entender su forma de almacenar la información en su propio repositorio).?

Ya para finalizar el tema de Marp y los emoticones, esos comandos o palabras claves (que no trae documentados cuántos ni cuales son) que os dijimos, los copiamos, encerramos entre «: :» y los pegamos en Marp para producir la siguiente captura (otra nota: los emoticones se ven afectados en tamaño si están precedidos como título «#», notad eso):

Marb emoticon emoji
Marb emoticon emoji
:angry::blush::broken_heart:
:confused::cry::frowning:
:heart::imp::innocent:

---

:joy::kissing::laughing:
:neutral_face::open_mouth::rage:

---

:smile::smiley::smiling_imp:
:sob::stuck_out_tongue::sunglasses:

---

:sweat::sweat_smile::unamused:
# :wink:

<!---
$size: A8
--->

Podéis obtener una lista ampliada, nemotécnica, en este enlace cuyo encabezado anuncia las páginas web y/o aplicaciones que utilizan esos emoji. Por ejemplo :cat: es más fácil de memorizar que U1F408, caracter unicode, y que funciona sin problemas con Marp. En dicha página hacéis click en el emoji que os guste y es copaido la palabra clave con su par de dos puntos, y pegáis en MArp. Un código que no veréis es el de GitHub :octocat: (combinación de pulpo con gato) así que no es una lista definitiva, por ahora.


Nota «final» sobre el tema?: estos emoticones que véis son los de WordPress, que Twitter tiene los suyos propios (acá está cómo enlazar el CDN a vuestras páginas web y/o aplicaciones web y acá un ejemplo de vista previa de las imágenes obtenidas que por curiosa coincidencia son los mismos del mapa de caracteres de Ubuntu ? je, je, je)

 


Actualizado el domingo 11 de junio de 2017.

Una lista completa de los códigos nemotécnicos de Marp los encontraréis en esta dirección: https://github.com/markdown-it/markdown-it-emoji/blob/6a65f5183fe0145219805040988341bf76ade32e/lib/data/full.json

Ofrecemos disculpas por no haber investigado lo suficiente. Esa sí es una lista completa de los caracteres emoji y soportados por Marp porque forma parte de sus componentes y compilación.


Enlaces web.

Los enlaces web o hipervínculos en Marp los podemos declarar de forma implícita y explícita (forma recomendada):

  • De manera implícita: si escribís «http://» más un caracter cualquiera, Marp lo convierte de inmediato en un enlace a la derecha en la ventana de visualización. También cuela «www.» más al menos dos caracteres.
  • De forma explícita: como dicta el MarkDown: un par de corchetes rectos (opcionales) donde colocaremos el texto del enlace y un par de paréntesis (curvos) donde colocaremos el enlace web en sí mismo.
Marp enlaces web
Marp enlaces web

Antes de hablar de las ecuaciones matemáticas…

…debemos indicaros que si necesitamos mostrar el código fuente en MarkDown a nuestra audiencia debemos encerrarlas entre triple comillas simples y Marp los interpretará como texto simple, es decir, no lo «ejecutará», no hará «parser».

Marp mostrar código MarkDown a la audiencia
Marp mostrar código MarkDown a la audiencia

Ecuaciones matemáticas.

Y acá lo que nos apasiona de tanto en tanto: las matemáticas, especialment el cálculo infinitesimal. Para ello Marp tiene un suplemento que debemos ingresar entre par de símbolos de pesos (o lo que sería con el paso del tiempo como símbolo de dólar). Cualquier texto que escribamos lo representa tal cual pero si lo antecedemos de cierta sintaxis comenzaremos a escribir nuestras fórmulas (no os preocupéis, no nos extenderemos mucho a favor de vuestra paciencia).

Fórmula de Euler.
  • Claro, cualquier texto lo representa tal cual…
  • … pero si lo antecedemos con un «_» tendremos un subíndice.
  • Con «^» lo convertiremos en superíndice.
  • Para agrupar estos subíndices o superíndices los encerramos entre llaves «{}»
  • Para multiplicar términos: «\cdot».
  • A «\cdot» le podemos agregar paréntesis para agrupar más términos.
  • Para mostrar tres puntos suspensivos: «\cdots».
  • ¡También podemos combinar «\cdots()»!
  • Ya con esto podremos representar la famosa fórmula de Euler:
Marp formula de Euler
Marp formula de Euler

Nota: cada fórmula matemática debe ocupar una o más líneas completas, no podemos intercalar fórmulas en una línea, por ejemplo. Opinamos que debería hacerlo y hasta podemos clonar el repositorio y empezar a programar, para eso es el software libre.

Identidad de Euler.
Marp identidad de Euler
Marp identidad de Euler

Símbolos y signos.

Es una lista larga, larguísima como la matemática misma pero los más comunes símbolos matemáticos tienen sus propios códigos:

  • Para representar ? usamos «\pi».
  • Para representar ?: «\phi»-
  • Para ?: «\theta»
  • Infinito: «\infty».

Operadores matemáticos simples y avanzados:

  • División: «\div».
  • Fracción: «\frac{}» -colocamos el numerador entre llaves y el denominador a continuación.
  • Sumatoria: «\sum» -la podemos combinar con superíndices y subíndices.
  • Raíz cuadrada: «\sqrt» más el número -o llaves, o paréntesis.
  • Paréntesis grandes, ideales para encerrar fracciones: «\Bigl(» y «\Bigl)».
  • Para representar integrales simples: «\int», dobles «\iint», triples «\iiint», integral de superficie «\oint».

Fórmula de cálculo de la constante e.

Marp cálculo de constante e
Marp cálculo de constante e

Exportar a formato PDF.

Probamos la exportación de archivos a formato PDF y no tuvimos ningún tipo de problema, si acaso un detalle que «no recuerda» los últimos archivos abiertos o guardados, «archivos recientes» les decimos. Incluso los emoticones fueron exportados y hermosamente dibujados -claro si originalmente fueron hechos en SVG nunca pierde calidad alguna al «pasar» de un lado a otro.

Conclusiones.

El software se ve realmente prometedor y aunque tiene la opción F11 pra verlo a pantalla completa no es lo mismo que un programa de presentación que se precie como tal: debe ser capaz no solo de usar las flechas de dirección del teclado para avanzar diapositivas sino que le falta aún programador de tiempo, música y lo más importante, ser capaz de detectar -y escoger- los múltiples monitores y/o proyectores que tengamos conectados a nuestro ordenador.

Esperamos os haya sido útil este vuestro -y nuestro- trabajo para la ampliación de conocimientos y saberes. 😉

Fuentes consultadas:

En idioma castellano:

En idioma inglés:

En idioma portugués:

En idioma japonés (nos disculpáis cualquier «fe de errata» al traducir):

Download PDF

PHP Simple HTML DOM Parser

Download PDF

Para abrir el mes de junio seguimos el hilo en nuestros artículos que buscan difundir el conocimiento libre del Patrimonio Tecnológico de la Humanidad. En anterior oportunidad estudiamos PHP curl, una herramienta basada en cURL y por ende en libcurl (¡ea, esto último no lo mencionamos allá!). Como en ese caso obtuvimos un método para descargar páginas web enteras, incluso si hay que pasarle datos con el método POST y/o hay que introducir usuario y contraseña. Esta entrada busca extraer, analizar e incluso modificar dichos datos ¡vente con nosotros!

Seguir leyendo

Download PDF

PHP y cURL

Download PDF

Suena incoherente: usamos curl en nuestra línea de comandos frecuentemente para diversidad de tareas pero no sabíamos que el lenguaje PHP tiene su propia versión llamada, cómo no, curl. El asunto es cómo se implementa y qué podemos hacer, nosotros en la línea de comandos lo acompañamos en el trabajo con grep pero en PHP la cosa es un poco diferente, ¡vamos a averiguar cómo!

Introducción.

Exactamente cómo implementaron cURL en PHP no lo sabemos, tal vez PHP haga llamado directo al curl y recoja sus resultados, sirviendo entonces como intermediario solamente… No tiene sentido pero si analizamos que muchos sitios web compartidos con otros dominios tienen PHP pero a uno no lo dejan ingresar por la línea de comandos entonces ¡vaya que si vale la pena el trabajo intermedio!

Por otra parte puede ser que especulamos demasiado y los buenos desarrolladores de PHP tienen su propia versión… ¡pero recordad que trabajamos con Software Libre que permite la modificación y reutilización del código! Pero echemos una leve ojeada al comando curl.

Comando curl.

Ya sabemos como va es esto del software libre: hay más de 1400 colaboradores en curl y el proyecto está alojado en GitHub desde el año 2010; aceptan contribuciones bajo la forma de «pull requests»: en resumen uno copia y trabaja con esa copia privada modificandola -y mejorandola, por supuesto- y devolviendo el trabajo al original para su aprobación. No se garantiza que se acepte toda la propuesta, e incluso ellos podrán tomar ciertas cosas propuestas y otras no, o en el mejor de los casos todo vaya bien y nos convirtamos en el colaborador 1401… y así haremos nuestra contribución al Patrimonio Tecnológico de la Humanidad.

Pero ¿quiénes desarrollan curl? Daniel Stenberg -sueco, habitante de Estocolmo- es el principal desarrollador y comenzó el proyecto por allá en 1996 basado en el trabajo de un programador brasileño llamado Rafael Sagula. Esta sencilla herramienta herramienta carioca fue bautizada como httpget con unas cuantas centenares de líneas y Stenberg las amplió para liberarla en 1997 con el nuevo nombre de «HTTP proxy support». Pero con el advenimiento de «nuevos» protocolos al proyecto tales como GOPHER y FTP pronto dejó de tomar sentido llamarlo solamente «HTTP»… así que ese mismo año vio la luz la versión número dos.

Para 1998 más protocolos y capacidades fueron agregados así que volvió a cambiar de nombre para la versión 4.0 -manteniendo la numeración de versiones- así que el 20 de marzo de ese año marca el nacimiento formal de curl. El nuevo nombre hace alusión al programa del lado del cliente, de allí la letra «c» inicial. Las otras tres letras os lo podéis imaginar ya: Uniform Resource Locator -URL- o Localizador de Recursos Normalizados.

El mismo Stenberg reconoce que hay muchos proyectos con el mismo nombre curl pero para la época que ellos lanzaron la versión cuatro no había (o conocían) de otros proyectos con el mismo nombre. Es por ello que nosotros al principio especulamos del origen de curl en el lenguaje PHP, pero es que ¡Incluso existe un curl desarrollado en software privativo! (no le haremos publicidad pues no nos pagan por ello, buscadlo vosotros mismos con DuckDuckGo). Tan famoso es que ya se considera como verbo en idioma inglés y muchos creen que es un protocolo pues lo tratan como tal pero ya sabemos que en realidad es una navaja suiza con muchísimas funciones.

curl para la línea de comandos.

En principio el comando curl fue desarrollado para scripts ya que sus entradas y salidas utilizan las ya famosas stdin y stdout. No ampliaremos más porque en este blog hallaréis información sobre su uso con la línea de comandos. El artículo que motivó la publicación de esta entrada está en el siguiente «tuit» y precisamente es para la línea de comandos -y pretendemos que corra en PHP curl-:

También hemos recopilado con el paso del tiempo otros usos notables del curl en la línea de comandos:

 

curl para su uso como librería.

A partir del año 2000 fueron desarrolladas, o mejor dicho, el código existente fue migrado completamente como librerías y a partir de allí se le hizo una interfaz de usuario para la línea de comandos. Está escrito en lenguaje C y aún hoy en día dichas bases siguen sustentando el proyecto con la ventaja que se puede reutilizar en otros proyectos y compilarlos todos juntos. Seguimos sospechando que precisamente eso hicieron en PHP pero esa es nuestra humilde opinión que como reafirmamos: en software libre este comportamiento es un honor a su filosofía de desarrollo: ejecutar, estudiar, distribuir, mejorar y redistribuir.

Versiones actuales y desarrolladores estrellas.

Nosotros en nuestro GNU/Linux Ubuntu 16 tenemos instalada la versión 7.40.00 pero en realidad la última versión estable es la 7.54.0.

Si bien son muchísimos los colaboradores, es justo mencionar los que más han contribuido en los últimos años de una manera marcada y constante:

  • Daniel Stenberg.
  • Steve Holme.
  • Jay Satiro.
  • Dan Fandrich.
  • Marc Hörsken.
  • Kamil Dudka.
  • Alessandro Ghedini.
  • Yang Tse.
  • Günter Knauf.
  • Tatsuhiro Tsujikawa.
  • Patrick Monnerat.
  • Nick Zitzmann.

Disipación de toda duda.

En este punto de nuestra investigación nuestras sospechas se hacen realidad: uno de los primero lenguajes en adoptar la librería curl es precisamente PHP el cual motoriza un 25% de las páginas web a nivel mundial. El extracto , en inglés, reposa en el libro electrónico -liberado con licencia «Creative Commons»- «Everything about curl«:

The libcurl binding for PHP was one of, if not the, first bindings for libcurl to really catch on and get used widely. It quickly got adopted as a default way for PHP users to transfer data and as it has now been in that position for over a decade and PHP has turned out to be a fairly popular technology on the Internet (recent numbers indicated that something like a quarter of all sites on the Internet uses PHP).
A few really high-demand sites are using PHP and are using libcurl in the backend. Facebook and Yahoo are two such sites.

La traducción hecha por nosotros al idioma castellano:

El software de enlace (librerías) de curl para PHP fue uno, cuidado sino, el primero de los enlaces que realmente captura y lo usa ampliamente. Rápidamente fue adoptado como una manera por defecto para transferir datos y se ha mantenido en esa posición por más de una década mientras tque PHP se ha convertido en una tecnología bastante popular en internet (cifras recientes indican que algo asó como una cuarta parte de todos los sitios web en internet utilizan PHP).

Realmente unos pocos sitios web de alta demanda están usando PHP acompañado de las librerías de enlace de curl corriendo entre bamabalinas. Facebook y Yahoo son dos de tales sitios.

Protocolos soportados por curl.

HTTP, HTTPS, FTP, FTPS, GOPHER, TFTP, SCP, SFTP, SMB, TELNET, DICT, LDAP, LDAPS, FILE, IMAP, SMTP, POP3, RTSP y RTMP (esos son todos, por ahora -y vienen más, no se detiene el proyecto-).

PHP curl.

Ahora si que pasamos a hablar del software que nos ocupa en este vuestro sitio web de compartición del conocimiento. Como ya hemos hablado bastante de historia y teoría pasamos directamente a describir cómo trabajar con PHP curl:

  1. Inicializar curl con curl_init().
  2. Pasarle los parámetros – esencial es la URL – con curl_setopt().
  3. Retribuir y mostrar -o guardar- con curl_exec().
  4. Cerrar y liberar recursos con curl_close().

Nuestro primer ejemplo práctico.

Lo siguiente que haremos es abrir una ventana terminal, tomar nuestro editor de texto favorito y escribir el siguiente código para ser guardado en un archivo que llamaremos php_curl.php:
[cc lang=»php» tab_size=»2″ lines=»80
[/cc]

Por supuesto, llamad vuestro archivo como queráis, guardadlo en vuestra carpeta donde ejecute vuestro servidor PHP y dadle los permisos de lectura y ejecución necesarios. En la primera línea inicializamos, en la segunda línea le pasamos la dirección web deseada -un dominio que devuelve nuestra dirección IP asignada por nuestro ISP-, en la tercera línea lo ejecutamos y en la cuarta línea cerramos y liberamos recursos. Una explicación más detallada a continuación.

Inicialización.

Debemos crear una instancia y guardarla para futuras referencias, este objeto basado en curl nosotros lo llamamos $objCurl y este nombre es el que debemos pasar a los otros comandos. El comando curl_init() solamente acepta un parámetro, la URL que es un dato imprescindible, tal vez debido a ser tan importante fue el único que establecieron en este comando. Aunque en el ejemplo no lo colocamos por razones didácticas, de ahora en adelante «para que no se nos olvide» lo estableceremos siempre en la primera línea del script o guion del programa.

Configuración.

Este es el comando más denso, notad que le damos el nombre de configuración porque su nombre así lo sugiere: curl_setopt(), osea «setopt» -> «set options». Acepta tres parámetros, separados por comas:

  • Primero debemos indicarle el objeto que contiene la inicialización de curl, en nuestro caso la variable $objCurl.
  • Segundo le pasaremos el tipo de valor que le pasaremos en el tercer parámetro, en nuestro caso la URL y la constante que lo define -nombrada de manera nemotécnica- es CURLOPT_URL.
  • El tercer parámetro es el valor en sí mismo de lo que indicamos en el segundo parámetro.

Debemos indicaros que usamos una sola línea para configurar, pero pronto veremos que esta parte es la más abultada por la infinidad de datos y tipos de datos que podemos pasar. Es mejor que vayaís preparando para aprender que esta sección siempre será multilínea y que debemos indentarla y escribirla lo más explícito posible para corregir a futuro de forma fácil nuestro código.

Ejecución.

Simplemente le decimos a PHP que hemos terminado de establecer lo que queremos obtener –o lo que queremos enviar, ya veremos más adelante- y acepta un parámetro que sigue siendo el objeto que hemos creado y configurado. En este punto ya os recordaremos que estamos trabajando con funciones y este comando devuelve verdadero o falso para indicar si tuvo éxito (para comparar la respuesta usaremos siempre «==» para estar seguros del tipo de variable y el resultado obtenido). En el ejemplo no colocamos ninguna variable que reciba el resultado del que hablamos como función ¿dónde está lo que nos interesa? En realidad el valor numérico (verdadero o falso) es lo que podemos guardar en una variable, el resto del resultados se va al stdout y eso será lo que enviaremos al navegador web que solicitó nuestro primer guión PHP sobre curl. Debido a esto recibiremos el mismo código HTML de la página que estamos solicitando (pero con los enlaces web absolutos cambiados).

Si probáis con descargar diferentes páginas, unas funcionarán, otras no, todo depende de si la página es estática, dinámica, si tiene JavaScript, en fin, cantidad de cosas que pueden NO ser compatibles con PHP curl: por eso debemos aprender las muchísimas opciones de configuración que nos sean útil en cada trabajo que se nos presente para ganarnos así el pan nuestro de cada día como Dios manda.

Liberación de recursos.

Os podrá sonar que nos contradecimos con lo siguiente: la función curl_close() se encarga de cerrar, como su nombre indica pero no devuelve resultado acerca del trabajo que le mandamos a realizar. Consideramos que esto es un «bug» porque a la hora de detectar dónde fugan recursos en nuestro servidor deberemos recurrir a otras herramientas apartes de PHP, pudiendo ser evitado esto con una sencilla rutina de nuestra parte e indicar que está sucediendo y qué está mal. Ah, perdón, casi lo olvidamos: el parámetro único que acepta es el objeto que creamos -y queremos destruir- con curl_init().

Nuestro primer ejemplo práctico pero mejorado.

Un sencillísima rutina de control de errores nos puede ahorrar muchísimos dolores de cabeza.

Nota: hay mejores métodos para el manejo de excepciones, pero aprendamos poco a poco. Ah, y nosotros lo llamamos «control de errores» y eso tampoco es el nombre correcto (excepciones) pero así nos abstraemos.

Por ello reescribiremos nuestro ejemplo pero con condicionales if~else:
[cc lang=»php» tab_size=»2″ lines=»80″ widht=»10%»]
$objCurl = curl_init(«http://www.soporteweb.com/»);
if ($objCurl == true) {
$resul = curl_exec ($objCurl);
if ($resul == true){
curl_close ($objCurl);
} else {
echo «No se pudo ejecutar PHP curl
«;
}
} else {
echo «No se pudo inicializar PHP curl.
«;
}
?>[/cc]

Notad que pasamos de una buena vez el URL en en el inicio con curl_init(). Además guardamos el valor del resultado en una variable, evaluamos el valor que tiene y ejecutamos o mostramos un mensaje apropiado según la respuesta obtenida. Muchos programadores y programadoras piensan que hacer nuestro software de esta manera, aparte de ayudarnos a nosotros mismo, abre las puertas a los hackers cuando se presentan excepciones -o errores, como les llamamos- porque «develan mucho». Ese razonamiento es válido en el software privativo pero en el software libre no tiene asidero alguno porque cualquier hacker tiene acceso al código fuente, así que hagamos la depuración fácil para nosotros mismos.

Guardando el resultado en una «variable aparte».

Como explicamos PHP curl envía al stdout la respuesta y asu vez eso lo pasamos al navegador, ¿qué tal si analizamos primero lo que recibimos y luego lo reenviamos? Por ejemplo, podríamos «acomodar» los enlaces absolutos de las imágenes que contiene la página web que llamamos (URL). Para ello vamos a emplear culr_setopt() con CURLOPT_RETURNTRANSFER establecido en el valor 1, mirad:

[cc lang=»php» tab_size=»2″ lines=»80″ widht=»10%»] $objCurl = curl_init(«http://www.soporteweb.com»);
if ($objCurl == true) {
curl_setopt ($objCurl, CURLOPT_RETURNTRANSFER, 1);
$resul = curl_exec ($objCurl);
if ($resul == true){
curl_close ($objCurl);
print «Nuestra direccion IP es: «;
print $resul;
} else {
echo «No se pudo ejecutar PHP curl
«;
}
} else {
echo «No se pudo inicializar PHP curl.
«;
}
?>[/cc]
Y así «manipulamos» el resultado con el texto que coloreamos en verde; ahora vamos un paso más allá. 😎

Guardando el resultado en un archivo.

Aunque ya tengamos el resultado deseado en una «variable» supongamos que estamos creando un robot (o bot como los mientan ahora en este siglo) y queremos guardar el resultado en un archivo ¿qué tiene que ver PHP curl con esto si ya sabemos el lenguaje PHP y sabemos como hacerlo aparte?

Pues resulta que con CURLOPT_FILE en curl_setopt() permite guardarlo en un archivo, pero antes tenemos que abrir el archivo y pasarle la «referencia» a PHP curl:
[cc lang=»php» tab_size=»2″ lines=»80″ widht=»10%»] $objCurl = curl_init(«http://www.soporteweb.com/»);
if ($objCurl == false) {
print «No se pudo inicializar PHP curl.
«;
} else {
$nom_arch = ‘PHP_curl.html’;
$arch = fopen( $nom_arch , «w»);
if ($arch == false ) {
print «No se pudo abrir el archivo ‘».$nom_arch.»‘
«;
curl_close ($objCurl);
} else {
$resp = curl_setopt ($objCurl, CURLOPT_RETURNTRANSFER, 1);
if ( $resp == false ) {
print «No se pudo establecer CURLOPT_RETURNTRANSFER.
«;
curl_close ($objCurl);
} else {
$resp = curl_setopt ($objCurl, CURLOPT_FILE, $arch);
if ( $resp == false ) {
print «No se pudo establecer CURLOPT_FILE.
«;
curl_close ($objCurl);
} else {
$resul = curl_exec ($objCurl);
if ($resul == false) {
echo «No se pudo ejecutar PHP curl.
«;
} else {
print «El archivo fue guardado con el nombre ‘PHP_curl.html’.
«;

// curl_close NO devuelve resultado:
curl_close ($objCurl);
}
}
}
}
}
?>[/cc]

Si tenéis problemas para escribir el archivo en disco REVISAD vuestros derechos de escritura para PHP especialmente para el grupo «www-data».

Así de sencillo, con las correspondientes rutinas de depuración para nosotros. Como tal vez se vea un poco largo hemos coloreado las partes importantes para que sigáis el hilo. ¿Que por qué nos hemos ido por la negación siempre de primero? Pues revisando la función fopen() verificamos que si es exitosa devuelve una referencia al archivo más no un valor de tipo booleno -verdadero-. En cambio si falla la función siempre devuelve un valor boleano falso. Lo de seguir usando la negación por defecto es para llevar el mismo estilo parejo al resto del código.

Mejorando la claridad de la sintaxis con ayuda de exit().

Una función «vieja» en PHP es la función die() que es totalmente equivalente a exit() que es más «elegante». El chiste del asunto es emplear la conjunción or (operador lógico «o») para unir la acción que queremos realizar con la función exit(). Dicha función permite como parámetro una cadena de texto o un entero entre cero y 254 (el 255 está reservado para uso exclusivo de PHP). Nos gusta mejor la opción de pasarle una cadena de texto con el mensaje que queremos presentar al usuario ¡o a nosotros mismos!

Otro punto importante es que la función exit() aparte de mostrar mensaje y cerrar adecuadamente los objetos en memoria es que sale inmediatamente y no ejecuta el resto de las líneas que quedan a partir de su llamada.

Veamos entonces cómo emplearlo en nuestra labor que hoy nos ocupa (para no alargar tanto cada línea fijaos el uso del punto y coma para separar bloques de código multilíneas):


  $objCurl = curl_init("http://www.soporteweb.com/")
    or exit("No se pudo inicializar PHP curl.
");

$nom_arch = ‘PHP_curl.html’;
$arch = fopen( $nom_arch , «w»)
or exit(«No se pudo abrir el archivo ‘».$nom_arch.»‘
«);

curl_setopt ($objCurl, CURLOPT_RETURNTRANSFER, 1)
or exit(«No se pudo establecer CURLOPT_RETURNTRANSFER.
«);

curl_setopt ($objCurl, CURLOPT_FILE, $arch)
or exit(«No se pudo establecer CURLOPT_FILE.
«);

curl_exec ($objCurl)
or exit(«No se pudo ejecutar PHP curl.
«);

print «El archivo fue guardado con el nombre ‘PHP_curl.html’.
«;

// curl_close NO devuelve resultado:
curl_close ($objCurl);
?>[/cc]

¡Qué gran mejora en la legibilidad! Debemos aclarar que exit() de manera implícita llama a los procedimientos de cierre y liberación de recursos de memoria (destructor lo nombran en lenguaje C++) así que como ven es una vía muy pragmática para nuestros propósitos.

Si queréis probar como funciona la rutina con control de excepciones, colocad una dirección web que no exista y mirad que sucede, ¡experimentad! También os recomendamos probar otros protocolos, por ejemplo FTP en un servidor público como por ejemplo «ftp://ftp.cesca.es/» donde veremos un listado de archivos disponibles para ser descargados.

Probando otros protocolos: FTP.

En el párrafo anterior os sugerimos probar el protocolo FTP y no hubo nada que cambiar en el código que teníamos -aparte de la URL, por supuesto-. Pero PHP curl tiene sus opciones y a continuación pasamos a revisar alguna de ellas. La primera que revisaremos limita el listado obtenido de archivos y directorios, osea, no muestra los permisos de cada uno de ellos. La sintaxis en el comando curl_setopt() -y todas las opciones utilizan esta función- es la siguiente:

[cc lang=»php» tab_size=»2″ lines=»80″ widht=»10%»]curl_setopt($objCurl, CURLOPT_FTPLISTONLY, 1)
or exit("No se pudo establecer CURLOPT_FTPLISTONLY");
[/cc]

Si el servidor FTP no fuera público o exigiera una conexión tipo anónimo usaremos esto:

curl_setopt($objCurl, CURLOPT_USERPWD, "anonimo:su@correo-e.com")
    or exit("No se pudo establecer CURLOPT_USERPWD");[/cc]
Con esta novedad de introducir credenciales de conexión nos encontramos con otro tipo de manejo de excepciones: dado el caso las credenciales no funcionen (mala escritura, contraseña vencida, usuario inexistente, etc) dentro del obejto PHP curl se guardará en una instancia aparte el resultado del intento de conexión, para ellos contamos con:
[cc lang="php" tab_size="2" lines="80" widht="10%"] echo curl_error($objCurl);[/cc]
https://twitter.com/souzace/status/868869012414840832

Pasando valores por medio del método POST.

Finalmente llegamos al meollo del asunto: poder pasar a un servidor web una o más variables por medio del método POST a un servidor web. Para propósitos de aprendizaje diremos que es uno de los métodos más populares debido a su cierta privacidad ya que el usuario no puede ver el enlace como en el método GET y tampoco es «cacheable» por los navegadores web.

Primero haremos una rchivo que nos muestre todas las variables que reciba y las liste por pantalla, de manera increíble solo necesita una sola líneas de código (guardar con el nombre de «curl_post.php«):


  var_dump($_POST);
?>[/cc]

Una vez tengamos este archivo ya sea en nuestro servidor local o en nuestro servidor remoto podremos comenzar a escribir el siguiente script:


 $objCurl = curl_init("http://localhost/curl_post.php")
 or exit("No se pudo inicializar PHP curl
");

curl_setopt($objCurl, CURLOPT_POST, 1)
or exit(«No se pudo establecer CURLOPT_POST»);

//Pasamos las variables que nos interesan al servidor
curl_setopt($objCurl, CURLOPT_POSTFIELDS, «var1=uno&var2=dos&var3=tres»)
or exit(«No se pudieron establecer las variables en CURLOPT_POSTFIELDS»);

curl_exec ($objCurl)
or exit(«No se pudo ejecutar PHP curl.»);

curl_close ($curl);
?>[/cc]
Debido a los mensaje que incluimos en cada exit() y con el coloreado del código no hay nada que explicar… excepto unas cuantas acotaciones:

  • Las variables que pasamos en el método POST deben estar por pares unidas con el ampersand y separadas por medio de un signo de igualdad.
  • Los espacios no se permiten, debemos pasar «%20» o mejor dicho debemos darle un formato especial antes de enviarlo. El comando que nos ayudará será urlencode() y para nosotros castellanohablantes es importante representar bien los acentos, etc.

[cc lang=»php» tab_size=»2″ lines=»80″ widht=»10%»] //Pasamos las variables que nos interesan al servidor
$var_post = urlencode(«var1=Venezuela&var2=América del Sur&var3=Güigüe»);
curl_setopt($objCurl, CURLOPT_POSTFIELDS, $var_post)
or exit(«No se pudieron establecer las variables en CURLOPT_POSTFIELDS»);[/cc]

Fuera de tema: «Tamper data for Mozilla Firefox».

Adam Judson es un desarrollador que tiene -nos tiene- como usuarios a más de 80 mil personas en su trabajo de programación desde el año 2007. Él desarrolló «Tamper Data» para este popular navegador, una herramienta para, según sus propias palabras «pruebas de seguridad en aplicaciones web por medio de la modificación de los parámetros POST».

Dicha herramienta la podemos instalar en nuestro navegador (requiere reinicio del navegador y no es compatible con «Google Web Accelerator») y con ella podremos visitar cualquier sitio web que utilize envio de datos POST y al activarlo en una ventana aparte mostrará sin molestar ni influir en nada el tráfico saliente de nuestro ordenador por medio de nuestro navegador web Firefox. ¿Por qué anuncia pruebas de seguridad? Porque nosotros muy bien sabemos como programadores que el código fuente de nuestras aplicaciones web están a la vista de los usuarios ¿pero que tal lo que no se ve? Pues acá entra «Tamper Data»: por más que coloquemos validación HTML5 y JavaScript del lado del cliente, si no utilizamos HTTPS el tráfico entre el usuario y nuestro servidor puede ser modificado por terceros. Y aunque si usaramos HTTPS tampoco podemos confiarnos de nuestros usuarios, verbigracia la misma herramienta que estamos recomendando puede modificar los datos si en la venta que se nos abre hacemos click en «modificar». Al activar este botón, cuando sale algo de nuestro ordenador nos pregunta si deseamos modificar algún dato, ¡y allí podremos echar por tierra toda la hermosa programación hecha en HTML5 y javaScript!

Este comentario es «fuera de tema»: para combatir esto último lo que debemos hacer es, en lenguaje PHP -o vuestro lenguaje utilizado- volver a validar los datos recibidos desde el usuario, ¡PERO HAY MÁS! Es obligatorio agregar «disparadores» y «restricciones» incrustados en nuestra base de datos (recomendamos PostgreSQL por su capacidad de incluso aceptar guiones en lenguaje Python) para volver a validar datos al agregar los datos a nuestro motor informático. Más detalles escapan de esta entrada, pero este resumen es el mejor que podemos expresar al respecto.

Ejecutando PHP curl en modo de depuración.

«Verbose» en idioma inglés describe un modo de hablar más de lo necesario. Pero en nuestro mundo del software libre nuestra búsqueda del conocimiento es insaciable, «solo sabemos que no sabemos nada» por ello le dedicamos esta sección empinada a ahondar en PHP curl. Aparte de aprender más y mantener nuestro cerebro haciendo ejercicios, debido a la gran cantidad de protocolos y opciones es sumamente fácil para nosotros el cometer errores solicitando opciones inexistentes o incompatibles entre ellas, si son varios los parámetros que les pasemos.

Para activar el modo de depuración -vamos que la traducción al castellano de «verboso» no cuela- en PHP curl echamos mano de la alternativa CURLOPT_VERBOSE en la ya consabida función curl_opt() ¡pero esperen -como dice el «infomercial» de T.V.- hay más! PHP curl, dijimos, lo tenemos claro, emplea stdin y stdout que son los más conocidos pero también utiliza stderr ¡para algo que no es error, sino DEPURACIÓN! Teoricamente no debería ser pero en la práctica, el mundo real esto es de facto que lo hacen -y haremos-: capturar el stderr para llevar los mensajes de depuración hacia un archivo de escritura y de adición. Este archivo si no está creado, lo hace, y lo abre para agregar dichos datos y si existe le adiciona al final, de tal manera que llevamos una especie de bitácora para nuestro estudio y control.


  $ObjCurl = curl_init()
    or exit("No se pudo inicializar PHP curl.
");

curl_setopt ($ObjCurl, CURLOPT_URL, «http://www.soporteweb.com»)
or exit(«No se pudo establecer la URL.
«);

curl_setopt($ObjCurl, CURLOPT_VERBOSE, 1)
or exit(«No se pudo establecer el modo de depuración.
«);

$verbose_arch = fopen(‘verbose.txt’, ‘a’);
curl_setopt($ObjCurl, CURLOPT_STDERR, $verbose_arch)
or exit(«No se pudo establecer CURLOPT_STDERR
.»);

curl_exec ($ObjCurl)
or exit(«No se pudo ejecutar PHP curl.
«);

curl_close ($ObjCurl);
?>[/cc]

Y veremos algo parecido a esto:

CURLOPT_VERBOSE
CURLOPT_VERBOSE

Explicamos que:

  • Las líneas que comienza con un asterisco son mensajes informativos de PHP curl.
  • Las líneas que comienzan con «>» es información que se le envia al servidor web, ftp, etc.
  • Las líneas que comienzan con «<» es la información que recibimos de tal servidor.
  • Los servidores web basados en ASP.NET devolverán un error «HTTP/1.1 500 Internal Server Error» y no podremos hacer nada ya que no se rigen por las normas comunes basadas en RFC y recomendaciones de WWW.

Otros usos para PHP curl.

Por nuestros experimentos vimos que PHP curl permite grabar en archivos «flujos de datos» de una manera básica, sin estar amarrado a protocolos (si lo usamos con FTP veremos que nos hacen falta los comandos populares y que solo podremos usar si tenemos un cliente FTP como tal). Eso deja abierta la posiblidad a darle infinidad de usos sin siquiera saber -ni preocuparnos- «con quien estamos hablando». Un ejemplo de ello es con el acceso a servidores con tecnología ASP.NET o la mismisa consulta de nuestra dirección IP que devuelve un resultado no normalizado ni con metadato alguno (solo nosotros, seres humanos, estamos con la plena certeza que es una dirección IPv4).

Por ejemplo, si en vez de usar soporteweb.com para retribuir nuestra dirección IPv4 usamos el servicio que presta icanhazip.com en el modo de depuración veremos algo como esto:

icanhazip.com Get the facts
icanhazip.com Get the facts

Y al seguir el enlace indicado abrimos el blog de Major Hayden (sí, ese es el nombre, no no es mayor de ningún ejército ni alcalde de ninguna ciudad) un administrador de sistemas GNU/Linux con 6 años de experiencia quien ha tenido excelentes maestros y está dispuesto siempre aprender… como nosotros mismos, quienes escribimos y quienes leemos este humilde sitio web.

Auguramos que curl y PH curl seguirá creciendo y mejorando para nuestro beneplácito y que nosotros, a la larga, algún día aportaremos nuestro granito de arena a la causa del software libre, de una u otra manera, de manera inexorable.

curl_setopt(): parámetros mas socorridos.

La lista es larga en verdad pero mencionaremos, al menos, los que avizoramos de alguna utilidad dada la experiencia que hemos logrado a lo largo de los años:

CURLOPT_USERAGENT

Con esta opción podremos indicarle al servidor con el cual le estamos requiriendo información acerca de nuestra identidad. Curiosamente PHP curl por defecto no envía indentificación alguna acerca del nombre del software pero es que también el servidor que atiende la consulta tampoco la requiere como obligatoria. En la práctica les mostramos (las direcciones IP las ocultamos -junto con otros detalles- de las visitas a esta vuestra página web):

PHP curl no se identifica -por defecto-
PHP curl no se identifica -por defecto-

Así que le aplicamos código y así quedaría la visita de nuestro bot en cierne:

Usando PHP curl CURLOPT_USERAGENT
Usando PHP curl CURLOPT_USERAGENT

CURLOPT_CONNECTTIMEOUT

A veces estimamos en cuánto tiempo debería responder determinado proceso y si no se realiza pues no está bien afinado nuestro servidor no sin antes descartar fallas de internet, etc. Para ello CURLOPT_CONNECTTIMEOUT es el idóneo para que nuestro script no se cuelgue indefinidamente, al cabo de cierto tiempo que le establezcamos y si no logra conectar con el servidor la tarea finalizará. El tercer parámetro que pasaríamos a continuación es el número de segundos, lo cual es una eternidad en tiempo de computadores, por ello también contamos con CURLOPT_CONNECTIONTIMEOUT_MS que viene expresado en milisegundos si estamos realmente apurados.

Es una excelente opción para desarrollar herramientas de diagnóstico a equipos remotos y podremos llevar un ergistro de eventos en nuestra base de datos (sí, que ya hay mucho software para eso pero también hay tareas tan pequeñas que no necesitamos «una mandarria sino un simple martillito»)

CURLOPT_COOKIE y CURLOPT_COOKIEFILE

Una «cookie» en inglés o galletita en castellano, es una pieza de información que plantan los servidores web en nuestros navegadores para identificarnos de manera absoluta. Al igual que el método POST debemos saber el nombre de la galletita y por ende su contenido, así que no la generamos nosotros -obvio- pero si debemos tener una para poder obtener respuesta de algunos servidores, quienes comparan si tienen la galletita en su lista de memoria (las galletitas tienen vencimiento o validez en el tiempo) y así podrán:

  • bien sea aceptar nuestra petición ó
  • incluso devolvernos unos valores personalizados.

De allí viene el gran temor a la violación de nuestra privacidad, una delgada línea demarca las buenas de las malas intenciones.

De esto último viene la necesidad de CURLOPT_COOKIEFILE, muchas veces son tantas las galletitas usadas por nosotros los programadores que mejor es enviar un archivo completo con ellas incluídas. Aquí debemos colocar el nombre del archivo en la opción anterior debemos enviar los valores en sí.

Otra manera de pasar una gran cantidad de galletitas es pasar el jarrón completo, un fichero, y para que no se nos olvide la sintaxis le pusieron el curioso nombre CURLOPT_COOKIEJAR. Un ejemplo sería:

curl_setopt($objCurl, CURLOPT_COOKIEJAR, 'jarron_de_galletitas.txt');[/cc]

CURLOPT_SSL_VERIFYPEER

Con esta opción podemos deshabilitar que verifique certificados en una conexión https (o mejor dicho TLS). Esto normalmente está habilitado pero uno a veces necesita, por economía, un certificado autofirmado el cual no está validado ante ningún tercer ente. Con esta opción cambiada a false en el tercer parámetro evitaremos este problemita.

CURLOPT_FOLLOWLOCATION

Actualmente las redirecciones de página se ha vuelto el pan nuestro de cada día motivado a la popularidad de las páginas web. Una página de cualquier gobierno del mundo de muy seguro que tendrá miles y hasta millones de visitantes y como comprenderán un solo servidor web jamás ni nunca se daría abasto. Lo que se ha inventado es poner granjas de servidores en distintas partes del mundo con copias constantes de los dominios deseados y redireccionado el tráfico con ayuda de potentes DNS: todo esto se conoce como CDN o «Content Delivery Network».

La idea del asunto es que cuando uno solicita una página web los DNS encargados redireccionan nuestra solicitud a la granja de servidores más cerca a nosotros de manera geográfica donde habrá una copia de la web que queremos. ¿A qué viene todo este cuento con PHP curl? Que es muy probable que la respuesta que obtengamos será una cabecera tipo 300 indicandonos que la direcciíon adecuadad para nosotros y entonces volvemos a hacer la petición -la misma petición- pero a otro servidor más cercano (o mas desocupado, o que tenga nuestra idioma, etc. -el que nos convenga-).

PHP curl ya está preparado en ese escenario y estableceremos CURLOPT_FOLLOWLOCATION a verdadero y por defecto PHP curl redireccionará hasta un máximo de 5 oportunidades nuestra solicitud (más adelante veremos otra función que nos dirá cuántas redirecciones siguió con la variable CURLINFO_REDIRECT_COUNT establecida).

Un problema se presenta al hacer una consulta POST: después del primer redireccionamiento PHP curl NO HACE una consulta POST sino una consulta GET (por razones históricas y de costumbres en los navegadores) y esto es un problema porque son métodos distintos y no obtendremos respuesta (aparte de que nos volveremos «locos» buscando dónde está el error). Para prevenir este inconveniente en vez de fijar CURLOPT_POST a «true» tomaremos otra opción, CURLOPT_CUSTOMREQUEST fijado a «POST»:

curl_setopt($ObjCurl, CURLOPT_CUSTOMREQUEST, "POST");[/cc]

Otra advertencia más: cuando uno sube archivos por medio de CURLOPT_POSTFIELDS en la segunda redirección no será enviado dicho fichero. También para prevenir esto urge emplear CURLOPT_POSTREDIR fijado el valor a 3 para que maneje los redireccionamientos 301 y 302 reenviando el archivo en cada oportunidad (es más tráfico de datos pero ¿cómo hacemos con los CDN’s que llegaron para quedarse?).

Panorama general del resto de las opciones de curl_setopt()

Ya en este punto os habreis dado cuenta de la importancia de esta función, recordad que solo hemos visto apenas cuatro que van en este orden: curl_init(), curl_setopt(), curl_exec() y curl_close(); pues bien hay 23 funciones más de las cuales más adelante estudiaremos una de ellas (por ahora).

He aquí un listado clasificado por el tipo de contenido que hay que pasar en el tercer parámetro de curl_setopt(), de un vistazo (en marrón las que hemos visto y analizado):

Aquellas cuyo valor debe ser booleano (verdadero<>0 ó falso=0):
  • CURLOPT_AUTOREFERER
  • CURLOPT_BINARYTRANSFER
  • CURLOPT_COOKIESESSION
  • CURLOPT_CERTINFO
  • CURLOPT_CONNECT_ONLY
  • CURLOPT_CRLF
  • CURLOPT_DNS_USE_GLOBAL_CACHE
  • CURLOPT_FAILONERROR
  • CURLOPT_SSL_FALSESTART
  • CURLOPT_FILETIME
  • CURLOPT_FOLLOWLOCATION
  • CURLOPT_FORBID_REUSE
  • CURLOPT_FRESH_CONNECT
  • CURLOPT_FTP_USE_EPRT
  • CURLOPT_FTP_USE_EPSV
  • CURLOPT_FTP_CREATE_MISSING_DIRS
  • CURLOPT_FTPAPPEND
  • CURLOPT_TCP_NODELAY
  • CURLOPT_FTPASCII
  • CURLOPT_FTPLISTONLY
  • CURLOPT_HEADER
  • CURLINFO_HEADER_OUT
  • CURLOPT_HTTPGET
  • CURLOPT_HTTPPROXYTUNNEL
  • CURLOPT_MUTE
  • CURLOPT_NETRC
  • CURLOPT_NOBODY
  • CURLOPT_NOPROGRESS
  • CURLOPT_NOSIGNAL
  • CURLOPT_PATH_AS_IS
  • CURLOPT_PIPEWAIT
  • CURLOPT_POST
  • CURLOPT_PUT
  • CURLOPT_RETURNTRANSFER
  • CURLOPT_SAFE_UPLOAD
  • CURLOPT_SASL_IR
  • CURLOPT_SSL_ENABLE_ALPN
  • CURLOPT_SSL_ENABLE_NPN
  • CURLOPT_SSL_VERIFYPEER
  • CURLOPT_SSL_VERIFYSTATUS
  • CURLOPT_TCP_FASTOPEN
  • CURLOPT_TFTP_NO_OPTIONS
  • CURLOPT_TRANSFERTEXT
  • CURLOPT_UNRESTRICTED_AUTH
  • CURLOPT_UPLOAD
  • CURLOPT_VERBOSE
Aquellas cuyo valor debe ser numérico entero:
  • CURLOPT_BUFFERSIZE
  • CURLOPT_CLOSEPOLICY
  • CURLOPT_CONNECTTIMEOUT
  • CURLOPT_CONNECTTIMEOUT_MS
  • CURLOPT_DNS_CACHE_TIMEOUT
  • CURLOPT_EXPECT_100_TIMEOUT_MS
  • CURLOPT_FTPSSLAUTH
  • CURLOPT_HEADEROPT
  • CURLOPT_HTTP_VERSION
  • CURLOPT_HTTPAUTH
  • CURLOPT_INFILESIZE
  • CURLOPT_LOW_SPEED_LIMIT
  • CURLOPT_LOW_SPEED_TIME
  • CURLOPT_MAXCONNECTS
  • CURLOPT_MAXREDIRS
  • CURLOPT_PORT
  • CURLOPT_POSTREDIR
  • CURLOPT_PROTOCOLS
    • CURLPROTO_HTTP, CURLPROTO_HTTPS, CURLPROTO_FTP, CURLPROTO_FTPS, CURLPROTO_SCP, CURLPROTO_SFTP, CURLPROTO_TELNET, CURLPROTO_LDAP, CURLPROTO_LDAPS, CURLPROTO_DICT, CURLPROTO_FILE, CURLPROTO_TFTP, CURLPROTO_ALL
  • CURLOPT_PROXYAUTH
  • CURLOPT_PROXYPORT
  • CURLOPT_PROXYTYPE
  • CURLOPT_REDIR_PROTOCOLS
  • CURLOPT_RESUME_FROM
  • CURLOPT_SSL_OPTIONS
  • CURLOPT_SSL_VERIFYHOST
  • CURLOPT_SSLVERSION
  • CURLOPT_STREAM_WEIGHT
  • CURLOPT_TIMECONDITION
  • CURLOPT_TIMEOUT
  • CURLOPT_TIMEOUT_MS
  • CURLOPT_TIMEVALUE
  • CURLOPT_MAX_RECV_SPEED_LARGE
  • CURLOPT_MAX_SEND_SPEED_LARGE
  • CURLOPT_SSH_AUTH_TYPES
  • CURLOPT_IPRESOLVE
    • CURL_IPRESOLVE_WHATEVER (por defecto), CURL_IPRESOLVE_V4, CURL_IPRESOLVE_V6
  • CURLOPT_FTP_FILEMETHOD
    • CURLFTPMETHOD_MULTICWD, CURLFTPMETHOD_NOCWD, CURLFTPMETHOD_SINGLECWD.
Aquellas cuyo valor debe ser una cadena de texto:
  • CURLOPT_CAINFO
  • CURLOPT_CAPATH
  • CURLOPT_COOKIE
  • CURLOPT_COOKIEFILE
  • CURLOPT_COOKIEJAR
  • CURLOPT_CUSTOMREQUEST
  • CURLOPT_DEFAULT_PROTOCOL
  • CURLOPT_DNS_INTERFACE
  • CURLOPT_DNS_LOCAL_IP4
  • CURLOPT_DNS_LOCAL_IP6
  • CURLOPT_EGDSOCKET
  • CURLOPT_ENCODING
  • CURLOPT_FTPPORT
  • CURLOPT_INTERFACE
  • CURLOPT_KEYPASSWD
  • CURLOPT_KRB4LEVEL
  • CURLOPT_LOGIN_OPTIONS
  • CURLOPT_PINNEDPUBLICKEY
  • CURLOPT_POSTFIELDS
  • CURLOPT_PRIVATE
  • CURLOPT_PROXY
  • CURLOPT_PROXY_SERVICE_NAME
  • CURLOPT_PROXYUSERPWD
  • CURLOPT_RANDOM_FILE
  • CURLOPT_RANGE
  • CURLOPT_REFERER
  • CURLOPT_SERVICE_NAME
  • CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
  • CURLOPT_SSH_PUBLIC_KEYFILE
  • CURLOPT_SSH_PRIVATE_KEYFILE
  • CURLOPT_SSL_CIPHER_LIST
  • CURLOPT_SSLCERT
  • CURLOPT_SSLCERTPASSWD
  • CURLOPT_SSLCERTTYPE
  • CURLOPT_SSLENGINE
  • CURLOPT_SSLENGINE_DEFAULT
  • CURLOPT_SSLKEY
  • CURLOPT_SSLKEYPASSWD
  • CURLOPT_SSLKEYTYPE
  • CURLOPT_UNIX_SOCKET_PATH
  • CURLOPT_URL
  • CURLOPT_USERAGENT
  • CURLOPT_USERNAME
  • CURLOPT_USERPWD
  • CURLOPT_XOAUTH2_BEARER
Aquellas cuyo valor debe ser una matriz:
  • CURLOPT_CONNECT_TO
  • CURLOPT_HTTP200ALIASES
  • CURLOPT_HTTPHEADER
  • CURLOPT_POSTQUOTE
  • CURLOPT_PROXYHEADER
  • CURLOPT_QUOTE
Aquellas cuyo valor debe ser un recurso de flujo de datos:
  • CURLOPT_FILE
  • CURLOPT_INFILE
  • CURLOPT_STDERR
  • CURLOPT_WRITEHEADER
Aquellas cuyo valor debe ser una función o una función de cierre:
  • CURLOPT_HEADERFUNCTION
  • CURLOPT_PASSWDFUNCTION
  • CURLOPT_PROGRESSFUNCTION
  • CURLOPT_READFUNCTION
  • CURLOPT_WRITEFUNCTION
Aquellas cuyo valor debe ser una muy específica:
  • CURLOPT_SHARE

Función curl_setopt_array.

Nos dimos cuenta como la función exit() mejoró muy bien la legilibilidad de nuestro código y además proporciona información a nuestros usuarios en caso de tratamiento de excepciones. Pero hay una manera aún mejor de configurar las opciones justo antes de ejecutar curl_exec() con el detalle que es como la famosa película de vaqueros: tiene lo bueno, lo malo y lo feo pero sin lo feo. Lo bueno -y muy bueno- es que como dijimos mejora la apariencia de nuestro código y abre nuevas posibilidades con el uso de una matriz: podemos realizar una función que consulte una base de datos y llene dicha matriz. Lo malo es que al pasar todo de un solo golpe a la unficón ésta acepta todo o no acepta nada y tendremos nuestra bella salida diciendo «no se pudo establecer culr_setopt_array» pero no nos indicará dónde, cuál es el elemento que falla.


  $objCurl = curl_init()
    or exit("No se pudo inicializar PHP curl.
");

$verbose = fopen(‘verbose.txt’, ‘a’)
or exit(«No se pudo abrir el archivo verbose.txt
«);
$opciones = array(
CURLOPT_URL => ‘https://icanhazip.com’,
CURLOPT_VERBOSE => 1,
CURLOPT_STDERR => $verbose
);

curl_setopt_array($objCurl, $opciones)
or exit(«No se pudo establecer curl_setopt_array()»);

curl_exec ($objCurl)
or exit(«No se pudo ejecutar PHP curl.
«);

curl_close ($objCurl);
?>[/cc]

Percataos que colocamos el URL en la matriz para abultar y activamos el modo de depuración de resto todo lo demás es el mismo ejemplo que colocamos anteriormente. Lo curioso del asunto es que curl_setopt() y curl_setopt_array() pueden trabajar juntos perfectamente, lo anterior lo podemos reescribir como lo próximo y funciona plenamente:


  $objCurl = curl_init()
    or exit("No se pudo inicializar PHP curl.
");

curl_setopt($objCurl, CURLOPT_URL ,’https://icanhazip.com’)
or exit(«No se pudo establecer el CULROPT_URL»);

$verbose = fopen(‘verbose.txt’, ‘a’)
or exit(«No se pudo abrir el archivo verbose.txt
«);
$opciones = array(
CURLOPT_VERBOSE => 1,
CURLOPT_STDERR => $verbose
);

curl_setopt_array($objCurl, $opciones)
or exit(«No se pudo establecer curl_setopt_array()»);

curl_exec ($objCurl)
or exit(«No se pudo ejecutar PHP curl.
«);

curl_close ($objCurl);
?>[/cc]

Analizando los resultados de la última conexión.

Comentamos que PHP curl puede utilizarse para fabricar una sencilla herramienta de monitoreo de servidores. Pensando en esto indagamos en ciertas opciones que trae la librería y de la cual podemos obtener gran cantidad de información, siempre pensando en guardarlo en una base de datos para su posterior análisis de manera masiva. Pero debemos comenzar por lo básico y no irnos precipitadamente.

Aparte de las opciones de depuración, que ya logramos vertirlas en un archivo que llamamos simplemente «verbose.txt» (y cuyo nombre podemos cambiar a la fecha y hora actual para que siempre sea un archivo distinto y almacenar -o borrar, o procesar, etc.- cuando queramos) podemos echar mano de otra función para obtener los datos de la conexión. Tal función es denominada curl_getinfo() a la que introducimos nuestro manejador creado por curl_init().

Esta función devuelve falso si no tiene información o una matriz con elementos predefinidos -no todos-. Para poder escribir esta matriz en un archivo agarramos a la función serialize() para convertirla en una cadena de texto antes de guardarla.

De una vez vamos a la práctica con el primer ejemplo que presentamos, el más «refinado» con las llamadas exit() ¿lo recordais? Pero vamos un paso adelante y lo modificamos, primero para que tome la URL por el método GET: escribimos en la barra de direcciones la ubicación de nuestro guion y al final agregamos un signo de cierre de interrogante con la palabra «url», luego un signo de igualdad y a continuación el dominio o página que queremos descargar y guardar -para luego analizar según el propósito que tengamos, que para cada persona es muy variopinto. Supongamos que nuestro guion está en nuestro servidor local y se llama «curl.php», el llamado sería el siguiente (obvien el prefijo «http://» porque lo agregamos en el script):

http://localhost/curl.php?url=www.ks7000.net.ve[/cc]

También agregaremos dos mensajes adicionales: si no se pasa una URL entonces alerta que debe pasar una y otro mensaje para indicar que ha sido guardada en un archivo (recordad que usamos la opcion CURLOPT_RETURNTRANSFER al valor de 1). Coloreamos el código para su mayor comprensión:


if ($_GET["url"])
{
 $objCurl = curl_init("http://".$_GET["url"])
 or exit("No se pudo inicializar PHP curl.
");

$nom_arch = ‘servidor.html’;
$arch = fopen( $nom_arch , «a»)
or exit(«No se pudo abrir el archivo ‘».$nom_arch.»‘
«);

curl_setopt ($objCurl, CURLOPT_RETURNTRANSFER, 1)
or exit(«No se pudo establecer CURLOPT_RETURNTRANSFER.
«);

curl_setopt ($objCurl, CURLOPT_FILE, $arch)
or exit(«No se pudo establecer CURLOPT_FILE.
«);

curl_setopt ($objCurl, CURLOPT_CONNECTTIMEOUT, 7)
or exit(«No se pudo establecer CURLOPT_CONNECTTIMEOUT.
«);
curl_exec ($objCurl)
or exit(«No se pudo ejecutar PHP curl.
«);

$nom_arch = «servidor_respuesta.txt»;
$archivo = fopen($nom_arch, «a»)
or exit(«No se pudo abrir el archivo'».$nom_arch.»‘
«);

$resp = curl_getinfo($objCurl)
or exit(«No se pudo obtener información de la ultima conexion.
«);

fwrite($archivo, serialize($resp))
or exit(«No se pudo escribir en el archivo ‘».$nom_arch.»‘
«);

fclose($archivo)
or exit(«No se pudo cerrar el archivo ‘».$nom_arch.»‘
«);

// curl_close NO devuelve resultado:
curl_close ($objCurl);
echo «URL descargada y guardada.
«;
} else {
echo «Debe pasar una URL para ser descargada y analizada.
«;
}
?>

[/cc]

Es crucial llamar esta función ANTES de llamar la función curl_close() que es cuando aún existe el objeto en memoria.

Matrix con campos predefinidos.

Esos datos que guardamos en el anterior software que inventamos ya están seleccionados por los desarrolladores de PHP curl y son los siguientes (repetimos, NO son todos los disponibles):

  • «url»
  • «content_type»
  • «http_code»
  • «header_size»
  • «request_size»
  • «filetime»
  • «ssl_verify_result»
  • «redirect_count»
  • «total_time»
  • «namelookup_time»
  • «connect_time»
  • «pretransfer_time»
  • «size_upload»
  • «size_download»
  • «speed_download»
  • «speed_upload»
  • «download_content_length»
  • «upload_content_length»
  • «starttransfer_time»
  • «redirect_time»
  • «certinfo»
  • «primary_ip»
  • «primary_port»
  • «local_ip»
  • «local_port»
  • «redirect_url»
  • «request_header» (solamente está definido si CURLINFO_HEADER_OUT está establecido por una llamada previa a curl_setopt())

Totalidad de los campos de get_info()

Podemos solicitar cualquiera de estos campos pasando como parámetro los siguientes valores a la función curl_getinfo() -con una breve descripción y ordenados alfabéticamente-:

  • CURLINFO_APPCONNECT_TIME – Tiempo, en segundos, desde el inicio hasta la conexión/apretón de manos SSL/SSH del host remoto.
  • CURLINFO_CERTINFO – Serie de certificados TLS.
  • CURLINFO_CONDITION_UNMET – Información del condicional de timepo unmet.
  • CURLINFO_CONNECT_TIME – Tiempo, en segundos, que tomó el establecimiento de la conexión.
  • CURLINFO_CONTENT_LENGTH_DOWNLOAD – Logitud del contenido de la descarga, leída desde el campo “Content-Length:”.
  • CURLINFO_CONTENT_LENGTH_UPLOAD – Tamaño especificado de subida .
  • CURLINFO_CONTENT_TYPE – “Content-Type:” del documento solicitado. NULL indica que el servidor no envío un encabezado “Content-Type:” válido.
  • CURLINFO_COOKIELIST – Todas las cookies conocidas.
  • CURLINFO_EFFECTIVE_URL – Último URL efectivo.
  • CURLINFO_FILETIME – Hora del documento remoto obtenido; si devuelve -1, la hora del documento es desconocida.
  • CURLINFO_FTP_ENTRY_PATH – Ruta de entrada en el servidor FTP.
  • CURLINFO_HEADER_OUT – El string de la petición enviada. Para que funcione, se ha de añadir la opción CURLINFO_HEADER_OUT al manejador, llamando a curl_setopt()
  • CURLINFO_HEADER_SIZE – Tamaño total de los encabezados recibidos.
  • CURLINFO_HTTP_CODE – Último código HTTP recibido.
  • CURLINFO_HTTP_CONNECTCODE – El código de respuesta de CONNECT.
  • CURLINFO_HTTPAUTH_AVAIL – Máscara de bits que indica el/los método/s de autenticación disponible/s de acuerdo a la respuesta anterior.
  • CURLINFO_LOCAL_IP – Dirección IP local (fuente) de la conexión más reciente.
  • CURLINFO_LOCAL_PORT – Puerto local (fuente) de la conexión más reciente.
  • CURLINFO_NAMELOOKUP_TIME – Tiempo, en segundos, en resolver el nombre.
  • CURLINFO_NUM_CONNECTS – Número de conexiones que curl ha tenido que crear para lograr la transferencia anterior.
  • CURLINFO_OS_ERRNO – Número de error (errno) de un fallo de conexion. Es número es específico de cada SO y sistema.
  • CURLINFO_PRETRANSFER_TIME – Tiempo, en segundos, desde el inicio hasta justo antes de que comience la transferencia del fichero.
  • CURLINFO_PRIMARY_IP – Dirección IP de la conexión más reciente.
  • CURLINFO_PRIMARY_PORT – Puerto de destino de la conexión más reciente.
  • CURLINFO_PRIVATE – Datos privados asociados a este manejador de cURL, previamente establecidos con la opción CURLOPT_PRIVATE de curl_setopt()
  • CURLINFO_PROXYAUTH_AVAIL – Máscara de bits que indica el/los método/s de autenticaición proxy disponible/s de acuerdo a la respuesta anterior.
  • CURLINFO_REDIRECT_COUNT – Número de redireccionamientos, con la opción CURLOPT_FOLLOWLOCATION habilitada.
  • CURLINFO_REDIRECT_TIME – Tiempo, en segundos, de todos los pasos de redireción antes de que la última transación haya empezado, con la opción CURLOPT_FOLLOWLOCATION habilitada.
  • CURLINFO_REDIRECT_URL – Con la opción CURLOPT_FOLLOWLOCATION inhabilitada: URL de redirección encontrado en la última transacción, que debería ser solicitado manualmente luego. Con la opción CURLOPT_FOLLOWLOCATION habilitada: está vacío. El URL de redirección en este caso está disponible en CURLINFO_EFFECTIVE_URL
  • CURLINFO_REQUEST_SIZE – Tamaño total de las peticiones realizadas, actualmente solo para peticiones HTTP.
  • CURLINFO_RESPONSE_CODE – El último código de respuesta.
  • CURLINFO_RTSP_CLIENT_CSEQ – Siguiente CSeq cliente de RTSP.
  • CURLINFO_RTSP_CSEQ_RECV – CSeq recivido recientemente.
  • CURLINFO_RTSP_SERVER_CSEQ – Siguiente CSeq servidor de RTSP.
  • CURLINFO_RTSP_SESSION_ID – ID de sesión de RTSP.
  • CURLINFO_SIZE_DOWNLOAD – Número total de bytes descargados.
  • CURLINFO_SIZE_UPLOAD – Número total de bytes subidos.
  • CURLINFO_SPEED_DOWNLOAD – Velocidad media de descarga.
  • CURLINFO_SPEED_UPLOAD – Velocidad media de subida.
  • CURLINFO_SSL_ENGINES – Criptomotores OpenSSL admitidos.
  • CURLINFO_SSL_VERIFYRESULT – Resultado de la verificación del certificado SSL solicitado por la opción CURLOPT_SSL_VERIFYPEER.
  • CURLINFO_STARTTRANSFER_TIME – Tiempo, en sengudos, hasta que el primer byte está a punto de transferirse.
  • CURLINFO_TOTAL_TIME – Duración total, en segundos, de última transferencia.

Futuro de cURL.

Como bien es sabido por todos nosotros, Internet como tal está basado en las siete capas de red según el modelo de interconexión de sistemas abiertos (ISO/IEC 7498-1), más conocido como “modelo OSI”, (en inglés, Open System Interconnection) y cURL hace uso de la séptima capa para las transferencias por internet orientadas a ficheros. Por ello su autor Daniel Stenberg deja bien claro que eso es lo que seguirá haciendo cURL ahora y durante mucho tiempo. A continuación una traducción automatizada de su entrada en el blog al respecto:

No soy de los que pasan el tiempo mirando hacia el horizonte soñando con la grandeza futura y haciendo planes sobre cómo ir allí. Trabajo en cosas ahora mismo para trabajar mañana. No tengo idea de lo que haremos y trabajaremos en un año a partir de ahora. Conozco un montón de cosas en las que quiero trabajar a continuación, pero no estoy seguro de si alguna vez llegaré a ellas o si realmente enviarán o si tal vez serán reemplazadas por otras cosas en esa lista antes de que llegue a ellas.
El mundo, Internet y las transferencias cambian constantemente y nos estamos adaptando. No hay sueños a largo plazo más que apegarse al plan simple y único: hacemos transferencias de Internet orientadas a archivos utilizando protocolos de capa de aplicación.
Las estimaciones aproximadas dicen que ya podemos tener mil millones de usuarios. Lo más probable es que si las cosas no cambian demasiado drásticamente sin que podamos mantener el ritmo, tendremos incluso más en el futuro.

Resumen.

Recuerden lo que siempre dijo en vida nuestro Gran Maestro: «un punto, un punto y una línea recta«; aprovechen estos conocimientos para desarrollar programas y utilidades para fortalecer el Patrimonio Tecnológico de nuestra Humanidad no para escribir virus y gusanos que marguen las vidas de los demás.

<Esto es todo, pora ahora>.


Actualizado el sábado 27 de enero de 2018.

Recientemente, pocos días atrás, el creador de cURL, Daniel Stenberg, publicó la versión 7.58 la cual contiene una curiosa correción al proceso de agregar un «espacio en blanco» (sí, un simple y vulgar espacio en blanco) en el «pase» de las cabeceras URL (ver en GitHub el causante de este desaguisado) lo cual nos parece muy significativo, pues somos de los que insistimos y somos fastidiosos en corregir hasta el último caracter al programar (si véis algún error por estos lares hacednos un comentario abajo). Pero no somos los únicos, mirad el siguiente «tuit»:


Fuentes consultadas.

En idioma castellano.

En idioma inglés.


Download PDF

PMWiki tutorial

Download PDF

En el MarkDown tutorial que hicimos explicamos de manera rápida la manera de escribir una página web con un formato desenfadado y sin tantas pretensiones. También publicamos acerca de Marp, un software libre capaz de realizar presentaciones y exportar a PDF a partir de un fichero hecho con MarkDown. Analizando el software de familias Wikis nos topamos con PMWiki que tiene una peculiar manera de escribir código «pseudo HTML» y por ello comenzaremos explicando las reglas de sintaxis y luego veremos como se instala y mantiene una página web con dicha solución en software libre, ¡adelante!

PMWiki text markup.

PMWiki utiliza un lenguaje de marcado a diferencia del paradigma actual del siglo XXI: «lo que usted ve es lo que obtiene» («What You See Is What You Get» o por sus iniciales WYSIWYG). Esto último consiste en utilizar herramientas de modelado que presentan en tiempo real la apariencia del trabajo que hacemos sin importarnos cómo se logra ya que el «interprete» nos abstrae del código subyacente. El asunto es que nosotros nunca dejamos de estar conscientes que los ordenadores solo entienden de unos y ceros (y ni siquiera eso, ya que es una abstracción que nos hacemos: solo entiende con apagado o encendido, hay o no hay en el último de los casos).

Reglas básicas de edición en PMWiki.

Hay seis reglas básicas para editar las páginas web cuyo motor web es la PMWiki:

  1. Para comenzar un párrafo solo basta con una simple línea en blanco.
  2. Para comenzar una lista enumerada comenzamos cada línea con un caracter numeral»#»; una lista no enumerada cada línea utiliza un asterisco «*» (numerada NO quiere decir ordenada, cuidado con los «falsos amigos» en las traducciones del inglés al castellano).
  3. Para un título principal comenzamos cada línea con signo de cierre de admiración «!» seguido de un espacio y luego el texto deseado. Cada subtítulo lleva dos o más signos de cierre de admiración «!!», «!!!», etc.
  4. Para texto en cursivas lo encerramos con dos comillas simples (») y para texto en negritas tres comillas simples (»’).
  5. Para realizar un enlace web en nuestra propia wiki lo encerramos con dobles corchetes rectos «[[ nombre ]]» donde nombre es el archivo que contiene nuestra página, en realidad es un enlace relativo (muy útil si luego queremos «mudar» nuestra wiki).
  6. Si queremos enlaces web hacia otros sitios web también lo encerramos entre corchetes rectos doble y debemos escribir el enlace completo -vamos, dejad la pereza, escribid con todo y «http://«. También sirve para otros tipos de enlaces como el usado para enviar correo electrónico «mailto:«.

Párrafos y saltos de líneas.

Los párrafos se delimitan dejando una línea en blanco, por lo tanto todo lo que escribamos en varias líneas será presentado como un solo párrafo. Para los que amamos el utilizar la venta terminal para trabajar nos ofrece la ventaja de escribir con un máximo de 40, 80 o 90 caracteres de anchura lo cual nos permite una cómoda edición sin preocuparnos del ancho de pantalla que utilizarán nuestros usuarios.

papel pijama
papel pijama

Generalmente monitores con relación 16:9 que es apto para ver películas pero incómodo para ver párrafos muy anchos ya que dificulta seguir la línea que estamos leyendo -recordad el famoso papel pijama del siglo XX , pero bueno, ese no es nuestro problema sino del usuario de la página, je, je, je ? ).

Este párrafo aunque
tiene varias líneas
será mostrado como uno solo.
Este párrafo aunque tiene varias líneas será mostrado como uno solo.
Para unir una línea con otra \
usaremos la barra invertida \
(a pesar que este es el comportamiento \
predeterminado, unir líneas).
Para unir una línea con otra usaremos la barra invertida (a pesar que este es el comportamiento predeterminado, unir líneas).
Sin embargo, si necesitamos que el párrafo
tenga múltiples líneas,
como por ejemplo un diálogo,
debemos usar al final dos barras
invertidas en cada línea, ejemplo: \\
-"¿Qué dijo ella acerca del tema?". \\
-"Que eso no era problema de ella". \\
Sin embargo, si necesitamos que el párrafo tenga múltiples líneas, como por ejemplo un diálogo, debemos usar al final dos barras invertidas en cada línea, ejemplo:
-"¿Qué dijo ella acerca del tema?".
-"Que eso no era problema de ella".
Para forzar fin de línea y dejar
una línea de por medio \\\
usamos tres barras invertidas.
Para forzar fin de línea y dejar una línea de por medio


usamos tres barras invertidas.
Para forzar la separación de una línea
usaremos [[<<]] para indicar el corte.
Para forzar la separación de una línea usaremos
para indicar el corte.
Para indentar un párrafo
(que sirve para hacer citas o resaltar ideas)
usaremos "->"
"Citas Citables."
Mientras más guiones usemos más indentado el párrafo.
Para indentar un párrafo (que sirve para hacer citas o resaltar ideas) usaremos "->":
"Citas Citables"

Mientras más guiones usemos más indentado el párrafo.
Una cita que comienze con
una línea prominente es una
forma atractiva para ello
usaremos "-<"
"Cita con línea prominente muy larga para que se note"
Una cita que comienze con
una línea prominente es una
forma atractiva para ello
usaremos
"Cita con línea prominente
muy larga para que se note"
Para comentarios usaremos los
símbolos mayor que y menor
>>comment<<
este es un comentario
>><<
que por pares.
Para comentarios usaremos los
símbolos mayor que y menor
que por pares.

En la tabla anterior os mostramos de manera práctica los comandos y cómo se vería, sin embargo es un artilugio de programación que le hicimos a WordPress para ilustraros el temas, hay algunos detalles que no se ven igual en PMWiki (lo mejor sería hacer un subdominio y correr una pequeña wiki allí para que veaís bien claro el resultado).

Listas.

Ya sabemos que para hacer una lista debemos comenzar con un asterisco «*» cada línea, y si acaso quiséramos asignarle una numeración automática debemos usar un numeral «#». Cualquier línea a continuación que NO comience con asterisco o numeral es implícito que finaliza la lista.

Acá ampliamos un poco con las sublistas: una línea que comienze con dos asteriscos (despúes de una línea que comienze con un asterisco) se visualiza como una sublista:

* Esta es una lista.
* Segundo elemento de lista.
** Comienza sublista.
** Segunda línea de sublista.

Producirá el siguiente resultado:

  • Esta es una lista.
  • Segundo elemento de lista.
    • Comienza sublista.
    • Segunda línea de sublista.

Se pueden combinar:

* Lista
## Sublista.
## Dos.
## Tres.

Salida:

  • Lista.
    1. Sub lista uno
    2. Dos.
    3. Tres.

Algo que gusta mucho a los autores es la numeración romana o con letras del abecedario, ya sea en maypusuculas o minúsculas; esto se logra colocando las siguientes palabras claves luego de el o los asteriscos y/o numerales de cada línea (por supuesto, no se mostrará al usuario dichas palabras claves al momento de «servir» el artículo wiki):

  • %roman%
  • %ROMAN%
  • %alpha%
  • %ALPHA%

Ejemplos de códigos:

* %roman% Lista con números romanos.
* Línea dos en números romanos.
## %ALPHA% Sublista con letras del abecedario en mayúsculas.
## Segunda línea de sublista.

Y arrojaría lo siguiente:

WikiSandbox listas con numeracion romana y alfabetica
WikiSandbox listas con numeracion romana y alfabetica

Estos «trucos» necesarios para mostrar en WordPress listas y sublistas a «nuestra manera personalizada»  tendrán su artículo aparte y será un complemento a nuestro tutorial HTML5 para no hacer ese tutorial más voluminoso de lo que ya es -y enseñar a usar WordPress, que ni un temita le hemos dedicado a nuestro «motor» de blog.

Este concepto de palabras claves se repite si debemos forzar la numeración u orden: «%item value= número%«.

También si queremos parar la numeración y reiniciarla solo debemos insertar una línea con la siguiente palabra clave: «[==]«:

# %item value=7000% Línea siete mil.
# Siete mil uno.
[==]
# Reinicia numeración.

Salida:

  1. Línea siete mil.
  2. Siete mil uno.
  1. Reinicia numeración.

Nota: el indentado que veís lo hace WordPress para alinear las listas con diferentes numeraciones, se agradece para nosotros los maniáticos del orden.

Listas con párrafos explicativos.

Para cada elemento de una lista podemos anexar un párrafo a continuación para ampliar o definir un concepto o descripción. El estilo indica que ha de ser lo más breve y conciso posible para mantener el panorama de la lista en sí misma. Dijimos que cualquier línea a continucación que NO comience con asterisco o numeral significa el fin de la lista pero he aquí que si una línea comienza con un espacio se considera esa línea como perteneciente al elemento de la lista que lo precede pero no se enumera -no es un elemento de la lista en sí-. Para lograr el indentado se debe finalizar la línea elemento de lista con «\\» (que aunque no es esctrictamente necesario, mejora el aspecto).

Un ejemplo:

'''Grandes venezolanos'''
* Simón Bolívar, Caracas 1783, Santa Marta 1830.\\
 ''«Llamarse jefe para no serlo es el colmo de la miseria»''.
* Francisco de Miranda, Caracas 1750, Cádiz 1816.
 ''«¡Le Venezuela est Blessée au coeur!»''.
* José Antonio Páez.

Produce lo siguiente:

Grandes venezolanos:

  • Simón Bolívar, Caracas 1783, Santa Marta 1830.

«Llamarse jefe para no serlo es el colmo de la miseria».

  • Francisco de Miranda, Caracas 1750, Cádiz 1816.

«¡Le Venezuela est Blessée au coeur!».

  • José Antonio Páez.

Línea horizontal.

Si escribimos el comando «—-» (cuatro o más guiones seguidos) en una sola línea de texto nos produce una línea horizontal gráfica que sirve para separar párrafos o denotar importancia como una advertencia -o el uso que queráis-.


Texto sin formato, tal cual.

Supongamos que en nuestra PMWiki queremos hacer un tutorial en castellano sobre todo esto que estamos explicando acá vía WordPress: para indicarle que no proceso nuestros código ejemplos y los muestre tal cual, cómo código que son debemos «escapar» el texto de código con «[@ texto código @]». Puede ser utilizado para un párrafo completo o para una o más palabras en un párrafo.

Para un «escapado» estricto utilizamos «[= texto código =]», la diferencia esta que con arroba se respetarán los saltos de líneas y espacios pero con el signo de igualdad se escribirá todo junto como un párrafo .

Texto con fuente monoespaciada.

Si además necesitamos una fuente monoespaciada, es decir, un tipo de fuente cuyas letras todas y cada una tienen el mismo ancho simplemente debemos comenzar la línea con un espacio (que no esté después de una lista, ojo con eso). Imaginad (o recordad) los famosos cuadernos cuadriculados para matemáticas, una letra por retícula.

cuaderno cuadriculado
cuaderno cuadriculado

Tablas.

Para las tablas emplearemos el caracter doble «tubería» o «||»:

  • La primera línea con doble tubería seguido del tipo de borde: «|| border=1».
  • La segunda línea con la primera fila de la tabla y cada elemento de columna separado con doble tubería.
  • Si es un encabezado de tabla, luego de doble tubería un signo de admiración de cierre.

Una tabla sin borde se logra con «border=0», de uno en adelante produce un borde doble con un sombreado que aumenta según aumenta el valor entero que le demos.

Existe una sintaxis alterna para tablas más avanzadas pero en honor a la verdad dicha sintaxis es igual de compleja que escribir en código HTML. Pensamos que solamente vale la pena para un cuadro de navegación como el siguiente:

(:table border=1 width=30% align=right bgcolor=#cccc99 cellspacing=0 : )
(:cellnr: )
'''Páginas de buscadores'''
(:cellnr: )
*[[https://duckduckgo.com/ | DuckDuckGo]]
*[[https://fr.wikipedia.org/ | Wikipédia L'encyclopédie libre]]
(:tableend:)

En esta imagen podemos ver la tabla avanzada mezclada con los ejemplos últimos, debajo de la imagen coloamos TODO el código completo que produce ese resultado en PMWiki:

PMWiki formatos de texto listas y tablas
PMWiki formatos de texto listas y tablas
(:table border=1 width=30% align=right bgcolor=#cccc99 cellspacing=0 :)
(:cellnr:)
'''Páginas de buscadores'''
(:cellnr:)
*[[https://duckduckgo.com/ | DuckDuckGo]]
*[[https://fr.wikipedia.org/ | Wikipédia L'encyclopédie libre]]
(:tableend:)
'''Grandes venezolanos'''
* Simón Bolívar, Caracas 1783, Santa Marta 1830.\\
 ''«Llamarse jefe para no serlo es el colmo de la miseria»''.
* Francisco de Miranda, Caracas 1750, Cádiz 1816.
 ''«¡Le Venezuela est Blessée au coeur!»''.
* José Antonio Páez.
|| border=0
||! head 1 ||! head 2 ||! head 3 ||
|| cell 1 || cell 2 || cell 3 ||
|| border=1
||! head 1 ||! head 2 ||! head 3 ||
|| cell 1 || cell 2 || cell 3 ||
|| border=2
||! head 1 ||! head 2 ||! head 3 ||
|| cell 1 || cell 2 || cell 3 ||
|| border=3
||! head 1 ||! head 2 ||! head 3 ||
|| cell 1 || cell 2 || cell 3 ||

Nota: la tabla avanzada se colocará siempre a la derecha, tal como instruimos en código pero al mismo nivel de los elementos que tenga a continuación -uno al lado del otro-

Formato de caracteres.

Otros comandos nos permiten dar formato al texto para representar fórmulas, citas, etc

* Texto con '^superíndices^'.
* Texto with '_subíndices_'.
* Texto {-tachado-}.
* Texto {+subrayado+} (poco utilizado, se confunde con hipervínculo).
* Texto [+grande+], [++más grande++].
* Texto  [-pequeño-], [--más pequeño--].

En la siguiente sección colocamos una imagen tomada del WikiSandBox: es un área donde podremos libremente practicar nuestros códigos, podremos hacer y deshacer sin problema alguno, programamos y visualizamos resultado mientras agarramos práctica, la idea es luego escribir rápidamente artículos completos y publicar de una vez sin mayor dilación.

«Sandbox» significa «cajón con arena» que nunca falta en los parques de los Estados Unidos y donde colocan a los pequeños y pequeñas para que desarrollen sus habilidades motoras sin peligro alguno; acá en Venezuela hacemos algo mucho mejor: los llevamos a las playas maravillosas de nuestro país.

Alineación de texto, color de fuente.

Por defecto el texto está alineado a la izquierda, pero podemos centrarlo comenzamos la línea con «%center%» y «%right%» para alinearlo a la derecha.

Para que el texto «flote» a la derecha sobre el siguiente párrafo que haya a continuación iniciamos con «%rfloat%» y si lo queremos en un marco «%rframe%«.

Para aplicar color simplemente escribimos el color, en inglés, encerrado entre signos de porcentaje. Esto se aplicará por defecto al resto del párrafo a partir del código, si necesitamos solamente colorear una palabra escribiremos «%blue% palabras a colorear %black%«. Por defecto el color de fuente es negro, por eso escribimos %black% pero eso no es necesariamente cierto, todo depende del estilo general de la PmWiki (tema avanzado). Lo correcto para restablecer el color es cerrar con doble signo de porcentaje «%%».

También se pueden combinar los comandos, por ejemplo centrado y en color rojo: «%center red%».

Formato de texto en WikiSandBox - PmWiki
Formato de texto en WikiSandBox – PmWiki

Alcance de los estilos.

No necesariamente se deben colocar los códigos al inicio de un párrafo, por ejemplo, a mitad de un párrafo podremos escribir «%p red% indicando que el párrafo, representado por la letra «p» sea rojo «red» sin importar dónde lo ubiquemos: al principio, en el medio o al final. Similar comportamiento aplica para otros elementos:

  • Imágenes: %img … (otros comandos)%
  • Texto de código: %pre (otros comandos)%
  • Lista: %list (otros comandos)%
  • Elemento de lista: %item (otros comandos)%

Estilos con nombres en castellano.

Podremos definir clases de estilos, definidos por nosotros mismos. En mejor uso es poder escribir en castellano, especialmente para aquellos u aquellas que no dominan ese idioma. Para ello al comienzo de un artículo podríamos escribir lo siguiente:

%define=amarillo color=yellow%
%define=fondo_amarillo bgcolor=yellow%
%define=azul color=blue%
%define=fondo_azul bgcolor=blue%
%define=rojo color=red%
%define=fondo_rojo bgcolor=red%

%amarillo%Conocerás los principios básicos%% de la programación en PHP como su sintaxis, estructuras de control, etc. %azul%Además explorarás un nutrido conjunto de características%% y funcionalidades, las necesarias para desarrollar la mayoría de las aplicaciones, %fondo_rojo%como el acceso a la base de datos%%, el sistema de archivos, etc.
Clases definidas en PmWiki
Clases definidas en PmWiki

Así entonces será más fácil recordar los comandos, pero supone escribir guiones al principio de cada artículo. Es mejor definir estilos globales, que funcionen en toda la página PmWiki alojada, eso es avanzado y más adelante lo estableceremos en la configuración de instalación.

Caracteres especiales.

Pues con nuestros teclados o copiando y pegando podemos escribir los caracteres «especiales»: las vocales acentuadas, el símbolo de la moneda euro €, etcétera y para ello rigen las mismas normas del HTML: la «á» se escribiría «&aacute;» el símbolo del €: &euro;.

Imágenes.

Por increíble que parezca, para mostrar una imagen en nuestra PmWiki simplemente colocamos el enlace hacia la imagen web… ¡y listo! (en WordPress es igual, aunque no lo creáis, pero este tutorial es de PmWiki y no otra cosa, disculpad).

El meollo del asunto es que normalmente gustamos de darle formato a las imágenes, texto alterno si el navegador no puede mostrar imágenes -o las tienen bloqueadas de alguna manera-, títulos, tamaños, bordes,  etc. Comencemos a realizar una lista con las principales características:

  • Comenzemos por establecer que una imagen ocupa una línea completa, imaginad que estamos escribiendo un párrafo. Luego cuando cojamos práctica podremos mezclar imagen entre párrafos para lograr bonitos acabados, verbigracia, como una enciclopedia merece; pero vayamos aprendiendo poco a poco.
  • Simplemente una imagen, sin más, colocamos una URL completa con alguno de los siguientes formatos de imágenes: gif, jpg, jpeg, png, svg, svgz. Dicha imagen debería residir en nuestro servidor por principios de ética de no «robar» el ancho de banda de los demás sitios web. Aunque PmWiki permite subir imágenes, dicha función, por seguridad, viene desactivada por defecto. En la sección de instalación y configuración tomaremos de nuevo el tema.
    • Ejemplo de imagen: http://pmichaud.com/img/misc/pc.jpg
    • La anterior imagen está alojada en el servidor web del autor de PmWiki, el Doctor Patrick Michaud, la imagen fue tomada de Flickr y tiene licencia «Creative Commons».
  • Cuando uno ubica, sin hacer click, el puntero del ratón (y nos disculpáis la redundancia) sobre una imagen web por más de 500 milisegundos (generalmente) nos aparece una ventanita con un texto que describe la imagen: para lograrlo en PmWiki debemos escribir a continuación y sin dejar espacio alguno, encerrado entre comillas dobles el texto deseado. También este texto es mostrado si por razón alguna el navegador NO puede mostrar la imagen, y los navegadores web modernos que narran las páginas web también toman este texto para los discapacitados visuales.
    • Ejemplo de «tooltip»: http://pmichaud.com/img/misc/pc.jpg»CLIPS»
  • Si queremos establecer un título a la imagen, después de las comillas dobles y sin espacio alguno insertamos un caracter «tubería» «|» e inmediatamente el texto deseado. En honor a la verdad si acepta espacios entre el caracter tubería pero recomendamos escribir todo junto para ayudarnos a recordar el proceso (y pulsar menos teclas para escribir más rápido).
    • Ejemplo de título a imagen: http://pmichaud.com/img/misc/pc.jpg»CLIPS»|»Clips coloridos»
  • Si queremos que la imagen en sí sea un enlace web debemos prestar mucha atención: debemos encerrarla entre corchetes rectos dobles pero dejando fuera el título de imagen, si es que la hubiere.
    • Seguimos con el mismo ejemplo, ahora más larga la línea:
    • [[http://pmwiki.org/|http://pmichaud.com/img/misc/pc.jpg»CLIPS»]]|»Clips coloridos»
  • Al igual que un texto, podemos alinear la imagen al centro o derecha colocándole de principio de línea los comandos %center% o %right% (por defecto se alinea a la izquierda):
    • %center%[[http://pmwiki.org/|http://pmichaud.com/img/misc/pc.jpg»CLIPS»]]|»Clips coloridos»
    • Ahora vamos viendo el porqué recomendamos eliminar los espacios, va larga la cosa. 🙂
  • Hasta ahora la imagen que queremos mostrar es tal cual, sin ninguna modificación al tamaño. Rogamos encarecidamente que subáis imágenes ligeras, en formato jpg preferiblemente y que midan menos de 50 mil bytes. Para redimensionar debemos usar:
    • A un ancho específico: %width=150px% (a 150 píxeles de ancho).
    • A un alto específico: %heigth%=100px% (a 100 píxeles de alto).
    • A una miniatura (66 x 32 píxeles, formato gif): %thumb%.
    • Intentamos seguir con el ejemplo planeado pero las múltiples combinaciones impiden que PmWiki redimensione la imagen, bien puede ser un excepción de PmWiki o nosotros desconocemos la sintaxis correcta pero nos decantamos -humildemente- por el error «bug» de PmWiki.
  • Para que al hacer click en la imagen se abra en una pestaña o ventana nueva debemos encerrar todo el enlace y sus opciones adicionales entre «%newwin% enlace_web %%» teniendo la precaución de colocarlo todo junto y justo antes de los corchetes dobles. Si quisieramos centrar la imagen primero debemos escribir %center% y luego el resto del comando y no al revés porque no lo tomara de forma debida y esperada.
  • Un interesante efecto para un párrafo es insertar la imagen a la izquierda o a la derecha de un párrafo que la describa o hable de ella, para lograr esto simplemente colocamos %rframe% o %lframe% antes del código de la imagen y luego al finalizar el código en otra línea el párrafo, sin dejar líneas vacías de por medio.
    • %rframe%https://www.ks7000.net.ve/wp-content/uploads/2017/05/PmWiki-logo-1.jpg párrafo
    • De nuevo, las opciones de redimensionamiento tampoco logramos hacerlas funcionar con %rframe%.
    • Imagen en cuadro flotando sobre texto alineado a la derecha
      Imagen en cuadro flotando sobre texto alineado a la derecha
  • Existen muchísimas más opciones para elt ratamiento de imágenes pero escapan a la simplicidad que queremos lograr y se aproximan más a la sintaxis de CSS y HTML, y es justo lo que queremos evitar, escribir en esos dos lenguajes de marcado.
  • Las imágenes se pueden combinar con tablas pero de nuevo, no son nada sencillo y queremos evitar su uso.
  • PmWiki es tan poderoso como queráis, no lo subestiméis, al modificar «config.php» tendremos cientos de personalizaciones, pero mantengamos la simplicidad, por favor -no todos nuestros usuarios serán tan avanzados en programación, con que aprendan unos cuantos comandos bastará para que escriban en nuestra Wiki.

Historia de PmWiki.

La palabra wiki proviene del idioma hablado en la isla de Hawaii, quincuagésimo estado federal de los Estados Unidos de América. Significa rápido y wiki wiki súper rápido (ya en los años 80 acá en Venezuela vendíamos un tinte para ropa llamado «wiki-wiki»: no teníamos dinero para comprar pantalones nuevos y los pintábamos de negro y listo, «pantalones nuevos» rápidamente).

Las páginas web que tienen un motor wiki son como cualquier otra página web pero tienen dos características únicas:

  • Tienen un botón con la palabra «editar» para que cualquiera colabore en ellas (y podemos subir o bajar los requerimientos de seguridad en la medida que nos sintamos cómodos).
  • No se necesita de conocimientos profundos sobre desarrollo web, con unos cuantos comandos como los que vimos arriba en el resumen de 6 pasos bastan para que se comienze a plasmar el aporte de cada quien.

Autor de PmWiki.

El caso concreto de PmWiki el Doctor Patrick Michaud (la letra «d» NO se pronuncia) es el autor con más de 40 años de experiencia en computación (graduado con «Post High Degree» en la University of Southwestern Louisiana -aquí le decimos Doctorado-) y podéis acceder a su página web http://www.pmichaud.com/ donde, faltaría más, faltaría menos con el motor PmWiki donde mantiene un resumen de su vida profesional y formas de contactarlo ya sea por correo eletrónico o redes sociales.

Dr. Patrick Michaud
Dr. Patrick Michaud

Filosofía de trabajo de PmWiki.

Fueron establecidas durante el desarrollo de PmWiki y aunque el Dr. Michaud comparte muchas de ellas no son exclusivas de su persona, de hecho mantienen un foro abierto a nuevas ideas y sugerencias para mantener activo este software a los requerimientos modernos de la humanidad.

Los pilares son:

  1. Preocupados sobre los autores más que por los lectores: buenos autores son difíciles de conseguir y «mantenerlos» en el proyecto priva sobre cualquier lector de la enciclopedia (crudo pero es la realidad).
  2. PmWiki no trata de reemplazar al HTML: ya hemos hablado sobre esto, se enfoca en ser algo simple y sencillo para los autores, sin embargo tiene poderosos sustitutos que pueden llegar a realizar casi lo mismo que el HTML pero no es nunca ese su objetivo.
  3. Pragmatismo sobre todo: se busca la utilidad por encima de la moda, algo bien estructurado en vez de ir a lanzarse a la primera por cualquier tendencia.
  4. Soporte colaborativo para el mantenimiento público de páginas web: autores y grupos de autores pueden ir construyendo un sitio para luego llegar a un punto de madurez y empezar a proteger con contraseñas ya sean páginas individuales o secciones o grandes secciones que busquen preservar los títulos, subtítulos e incluso párrafos e imágenes mientra otras áreas están libres y abiertas para captar nuevas ideas o registrar el simple pasar del tiempo. Precisamente éste es un ejemplo: un registro de cambios de un artículo (NO el registro de cambios de la página en sí) debería estar protegido al cabo de cierto tiempo, días o semanas, proque eso es historia y ya no cambiará (incluso se pueden dejar las referencias abiertas en pie de página si alguien quiere agregar algo al tema).
  5. Fácil de instalar, configurar y mantener: del dicho al hecho, las siguientes secciones hablan sobre ello.

Instalación de PmWiki.

Primero debemos descargarlo de forma comprimida desde PmWiki, solo pesa menos de medio megabyte, la versión estable 2.2.98 -ya os dijimos: PmWiki es sencillo y simple pero muy útil-.

Como un servicio a la comunidad por acá también la ponemos a la orden, si la queréis descargar desde acá.

Se ofrece paquetes adicionales para diferentes idiomas en esta dirección de la misma PmWiki.org pero deja mucho que desear por ahora para nuestro trabajo la vamos a dejar así, en purito inglés pero no creáis que nos hemos rendido con el castellano, de hecho tenemos en mente unas ideas laboriosas por realizar y una vez terminemos la publicaremos por acá.

Una vez descargado lo descomprimimos en nuestra carpeta /var/www/html -en nuestro caso usamos un servidor web Apache2 con PHP5 en nuestro ordenador en VirtualBox- y debemos darle los derechos adecuados de escritura para que se puedan grabar nuestras preferencias.

Se recomienda crear una carpeta llamada pmwiki en la carpeta pública de nuestro servidor web y redirigir debidamente modificando el .htaccess (o por otros métodos). No es la tarea de esta entrada y tomando en cuenta que tenemos un servidor de pruebas y por propósitos didácticos NO LO HAREMOS ASÍ sino que simplemente colocaremos los ficheros y directorios como si el servidor fuera dedicado a retribuir una sola página web.

Ficheros y carpetas de PmWiki.

Una vez hayamos copiado los archivos tendremos la siguiente estructura que pasamos a traducir directo del propio tutorial en inglés:

  • README.txt: un documento introductorio y contiene la licencia de uso GNU:
  • pmwiki.php: el archivo principal, el hace las veces del «index.php» en nuestro servidor Apache2.
  • local/: Carpeta que contiene los guiones de configuración local.
  • cookbook/ : Carpeta con»recetario» con programas agregados que enriquecen a PmWiki (suplementos).
  • docs/ : Documentación y guiones de ejemplo.
  • pub/ : archivos de acceso público.
    • pub/css/ : Archivos con hojas de estilo en cascada de los temas (suplementos).
    • pub/guiedit/ : (¡aún no hemos estudiado este directorio!).
    • pub/skins/ : «temas» para cambiar la apariencia y comportamiento de PmWiki.
  • scripts/ : Guiones que son partes de PmWiki.
  • wikilib.d/: Paquete de páginas predeterminadas de PmWiki.

Por ahora esos son los ficheros y directorios iniciales, los cuales, por seguridad, solo necesitamos que tengan derecho de lectura más no de escritura. Para poder guardar nuestras configuraciones y futuros artículos debemos tener derechos de escritura en una carpeta especial llamada «wiki.d/«.

¡Atención! no confundir con la carpeta wikilib.d

  • Dentro de esta carpeta wiki.d se guardarán nuestros artículos con el prefijo «PmWiki.» más el nombre del título que le pongamos al crearla.
  • Junto a estos archivos automáticamente PmWiki llevará de manera sincronizada otros ficheros donde se registran los cambios hechos, la configuración de la barra lateral izquierda e incluso un índice de páginas. No debemos preocuparnos por estos archivos, excepto respaldarlos regularmente fuera de nuestro sitio web y/o servidor de producción (si respaldamos en nuestro ordenador podremos llevar un respaldo adicional junto con un control de cambios al utilizar GitHub el cual es sin costo para proyecto públicos -proyectos privados se paga mensual en US$-).
  • El otro directorio que debe tener derechos de escritura si es que llegamos a habilitarlo es la carpeta «uploads» que viene a albergar los ficheros que subamos a nuestro servidor. Se le harán las mismas consideraciones del punto anterior.

Si nuestro servidor permite acceso vía SSH por ventana terminal usaremos el comando «chmod» para otorgar permisos de escritura, si es un servidor web compartido generalmente tenemos acceso vía softwfare CPANEL que permite lanzar un navegador de archivos y otorgar derechos de escritura a esas dos carpetas. También recordemos que el comando «chmod» funciona en muchos programas clientes FTP, así que cuando «subamos» los archivos de PmWiki podríamos cambiar de una vez los derechos de escritura.

Dado el caso que NO hayamos configurado lo anterior y nos decidimos por ejecutar directamente de una el fichero principal pmwiki.php éste nos lo recordará amablemente con un mensaje de que no podemos seguir adelante.

Ejecutando por primera vez pmwiki.php

Pues bien, acá se mostrará la página de bienvenida con tutoriales e indicaciones -en inglés- de todo lo que explicamos acá en idioma castellano.

Estableciendo «index.php» o «index.html»

Dependiendeo de como tengáis configurado vuestro servidor, necesitaréis un archivo llamado «index.php» o si tenéis configurado tratar los archivos con extensión .html como .php debeis escribir en él lo siguiente:

[cc lang=»php» tab_size=»2″ lines=»60″]<?php
include(«pmwiki.php»);

?>[/cc]

Modificando «config.php».

Lo que nos toca por hacer es configurar el archivo config.php en la carpeta «local/«. Dicho archivo es de solo lectura pero debemos tener permisos de escritura para copiarlo desde la plantilla llamada «sample-config.php» (carpeta «docs/») la cual modificaremos a nuestro gusto y conveniencia: en nuestro ordenador donde hayamos descargado y descomprimido PmWiki copiamos el archivo con el nombre «config.php» lo modificamos para luego subirlo (vía https o sftp) a nuestra carpeta «local/».

Este fichero contiene las configuraciones comunes pero vienen inactivas gracias a un caracter numeral al principio de cada línea de comando, eliminando dicho caracter las «descomentamos» y ponemos a nuestro servicio.

  • La primera línea que modificaremos es el título de nuestra página, por defecto reza «$WikiTitle = ‘PmWiki’;» cambiando solamente lo que está entre comilla simples.
  • La segunda línea a cambiar permite cambiar nuestro logotipo a una imagen tipo gif de 32 píxeles que diseñemos y con el nombre que querramos, cambiamos la siguiente línea QUE DEBEMOS DESMARCAR como comentario (fijaos en la ruta donde vamos a subir dicho archivo):
    • $PageLogoUrl = «$PubDirUrl/skins/pmwiki/pmwiki-32.gif«;
  • ¡Muy importante! la contraseña administrativa en la línea siguiente la cambiaremos a nuestro criterio:
    • $DefaultPasswords[‘admin’] = pmcrypt(‘secret‘);
  • Si quisieramos activar la subida de archivos, modificar la línea que activa (descomentarla) y fijar una nueva contraseña a nuestra conveniencia (y descomentarla también):
    • $EnableUpload = 1;
    • $DefaultPasswords[‘upload’] = pmcrypt(‘secret‘);
  • PmWiki permite unos botones gráficos para darle un pequeño toque «colorido» a nuestra página web, si deseais lo activaís descomentando la siguiente línea:
    • $EnableGUIButtons = 1;
    • PmWiki botones gráficos
      PmWiki botones gráficos

¡LISTO! Guardamos y copiamos a su ubicación final y vemos los cambios recargando la página.

Seguridad en PmWiki.

Al modificar config.php establecimos nuestra contraseña como administrador, nuestra llave para crear, modificar o  eliminar contraseñas, es el más alto nivel efectivo en nuestro sitio. La reservamos para nosotros, los programadores y encargados del mantenimiento y funcionamiento de la página web en sí ya que la mayor del tiempo serán los autores los que estarán a cargo de proteger sus propios trabajos.

El enfoque que utilizaremos, siempre pragmáticos, es de ir de menos a más, según nuestras necesidades, analizemos:

Grupo de 1 a 3 autores.

Siendo un grupo pequeño solo se necesita que a nivel global todos los botones de edición de página tengan una simple contraseña. Para lograr esto debemos descomentar y modificar (o agregar) la línea siguiente en /local/config.php

$DefaultPasswords['edit'] = pmcrypt('nuestra_contraseña_de_edicion');

Acá no hay más complicaciones, solo es cuestion de comunicarse entre ellos y verbalmente dirimir sus diferencias, en teoría no debería haber mayor problema y si lo hubiera nosotros como administradores deberemos tener la última palabra y «reiniciar» la contraseña a nivel global para excluir a algún miembro de la edición de artículos -caso extremo-. Luego veremos que tal vez tengamos unas tareas adicionales que realizar, tened paciencia y os explicamos, vamos a continuar con la idea de grupos.

Grupo de 3 a 12 autores.

Manejar a esta cantidad de personas la cosa se complica un poco. Tratar de reunirlos todos a la vez va a ser difícil y si se lograra se nos va a ir el tiempo en reuniones grupales, lo cual es mucho trabajo para el poco dinero que nos pagan por la tarea. ?

El mejor enfoque en este caso es establecer nosotros mismos normas de publicación (grupo de páginas) de caracter privado por lo que tendremos que establecer contraseñas para poder leer este particular grupo de páginas. Establecidas las normas, ya saben a qué atenerse. Una vez «tamizados» los autores podremos elegir a dos sub administradores que nos ayuden en nuestro trabajo, pero ¿cómo lograr esto sin dar nuestra contraseña de edición a los subadministradores? A nivel global se pueden establecer matrices de contraseñas (esto ya es lenguaje PHP en sí) de nuevo en el ya famoso archivo config.php:

$DefaultPasswords['read'] = array(pmcrypt('alfa'), pmcrypt('beta'));
$DefaultPasswords['edit'] = pmcrypt('beta');

«alfa» y «beta» serán dos contraseñas distintas, para elevar un autor a subadministrador (ojo, esta figura no está canonizada en el sistema PmWiki, la estamos «inventando» en este artículo práctico) pues le daremos una nueva contraseña que será «beta«. Es más, si son dos subadministradores, como proponemos ,nada nos impide generar una contraseña «gamma»:

$DefaultPasswords['read'] = array(pmcrypt('alfa'), pmcrypt('beta'), pmcrypt('gamma'));
$DefaultPasswords['edit'] = array(pmcrypt('beta'), pmcrypt('gamma'));

Luego veremos que tal vez tengamos unas tareas adicionales que realizar, tened paciencia y os explicamos, vamos a continuar con la idea de grupos.

Grupo de autores de hasta 100 autores.

Acá la cosa se pone «color de hormiga»: ya en este punto debemos habilitar usuario y contraseña (léase «login» y «password») para todos y cada uno de los usuarios a fin de determinar quién hizo qué y tomar las medidas correspondientes. ¿Recordáis la figura de subadministradores? Pues bien, ¡vamos a necesitar entre 3 y 6! Esto es así porque el mantener cuentas y contraseñas de usuario se va a llevar bastante trabajo y necesitamos

El primer paso para habilitar esta característica es agregar (o descomentar) la siguiente línea en /local/config.php:

include_once("$FarmD/scripts/authuser.php");

Demás está decir que ya habremos establecido nuestra contraseña de «admin», lógicamente, en vez de la que trae por defecto la instalación de PmWiki (un hacker -buenas intenciones- o un cracker -malas intenciones- lo primero que haría sería intentar entrar con esa contraseña por defecto).

La manera de registrar a los usuarios es editar una página llamada pmwiki.php?n=SiteAdmin.AuthUser, es decir, al guión principal llamado pmwiki.php le «pasamos» en la barra de direcciones un signo de cierre de interrogación y solicitará nombre de usuario y contraseña al editar (usaremos la superclave de admin) y agregaremos cada cuenta con la siguiente sintaxis:

nombre_de_usuario: (:encrypt contraseña:)

Guardamos la página y la contraseña se mostrará encriptada. Dichas cuentas, por manía de orden, la colocamos justo después del subtítulo «Login accounts» y más abajo veremos el subtítulo «Authorization groups» donde podramos definir los grupos de usuarios que inventamos, a saber: autores y subadministradores.

@autores: Kevin, Jimmy
@subadministradores: Kevin

Al crear este tipo de grupos de usuarios se nos facilita enormente la tarea de administración si invertimos el enfoque: nombramos a cada usuario a los grupos que puede pertenecer, el ejemplo anterior pero por usuarios:

Kevin: @autores, @subadministradores
Jimmy: @autores

¿En qué nos beneficia todo esto? En que en cada página podemos definir cuales grupos tienen acceso e incluso podemos delegar -con sumo cuidado- de poder editar la mismísa página SiteAdmin.AuthUser. A primer vista esto parecería una locura pero es que para definir cuentas de usuarios y grupos de usuarios la otra manera de hacerlo permitir editar el fichero config.php y esto no es para que lo haga todo el mundo, cualquier cosa  podría salir mal y tendríamos nosotros mismo que enmendar el capote.

Luego veremos que tal vez tengamos unas tareas adicionales que realizar, tened paciencia y os explicamos, vamos a continuar con la idea de grupos.

Grupos de 100 o más autores.

Manejar tal cifra de personas ya no es posible hacerlo así, «de manera manual», tendremos que recurrir al uso de protocolos y normas adecuados y que manejen bases de datos para llevar cuenta de todo. PmWiki ofrece acceso mediante el protocolo LDAP pero escapa al alcance de este tutorial. También existe apoyo para htpasswd: el cual utiliza el servidor Apache2 pero no supone ventaja alguna porque al igual que PmWiki se basa en texto plano -incluso encriptado- y no utiliza base de datos además deja por fuera a Ngix que es otro poderoso servidor web, así que no le vemos futuro a esa alternativa.

Además, para manejar tal cantidad de usuarios, se espera una gran cantidad de artículos y por ello debemos hacer uso de un manejador de base de datos que no exija demasiado recursos de cómputo: SQLite es el elegido para ello. Para habilitar su uso debemos descargar y ejecutar este guion creado por Petko Yotov con el cual creamos la base de datos, tablas, índices y relaciones y una vez hecho esto si que debemos modificar de nuevo el consabido config.php en alguna de sus primeras líneas lo siguiente:

[cc lang=»php» tab_size=»2″ lines=»60″]include_once(«$FarmD/cookbook/sqlite.php»);
$WikiDir = new PageStoreSQLite($WorkDir.’/pmwiki.sqlite.db’, 1);
$WikiLibDirs = array(
&$WikiDir,
new PageStore(‘wiki.d/{$FullName}’),
new PageStore(‘$FarmD/wikilib.d/{$FullName}’)
);[/cc]

El fichero pmwiki.sqlite.db será entonces el único que conservará las página que creemos y será el que dabamos respaldar llegado el momento necesario. Esto apenas es un resumen ya que todo programador sabe muy bien que no hay base de datos «rebeldes» sino mal administradas. Por ejemplo, de tanto en tanto deberemos ejecutar la orden pmwiki.php?action=vacuum; también podremos establecer un valor automático para que ejecuta esta acción por nosotros si lo establecemos en config.php:

$SQLiteAutoVacuum = 300;

Incluso si le colocamos el valor de cero (no ejecutar), siempre podremos hacerlo cuando necesitemos con ?action=vacuum.

Tareas adicionales.

Pues que varias veces nombramos unas dichosas «tareas adicionales» que debíamos realizar para «cerrar el círculo de seguridad» para ello los siguientes datos:

  • Las páginas y grupos de páginas les pueden ser establecidas, individualmente,
    • Contraseña de lectura read.
    • Contraseña de escritura write.
    • Contraseña de acceso a configurar las dos anteriores mediante attr.
  • Para modificar las contraseñas de lectura y escritura a una página debemos adicionar «?action=attr» al final en la barra de direcciones y así introducir nuestra contraseña de administrador (admin).
  • Para modificar las contraseña de lectura y escritura a un grupo de páginas debemos adicionar al final en la barra de direcciones lo siguiente (susitutid «GroupName» por el nombre del grupo de páginas:)
    • «?n=GroupName.GroupAttributes?action=attr«
  • Las contraseña son visibles para no pedir confirmación pero al ser guardadas serán debidamente encriptadas (cuidado con las miradas encima por encima de tus hombros).
  • En cada campo -lectura y escritura- de una página o grupo de páginas podremos:
    • Agregar una o más contraseñas simplemente separándolas por un espacio.
    • Agregar uno o más grupos nombrandolos precedidos de una arroba -ejemplo @subadministradores- y separándolos por un espacio entre ellos.
    • Si queremos que todos los miembros de un grupo tengan acceso usaremos «@nombre_grupo: *«.
    • Si de ese grupo necesitamos  exceptuar un usuario -que pertenece a ese grupo-:
      • «@nombre_grupo: *, -nombre_usuario«.
    • Establecer uno o más usuarios con la palabra clave «id:» y a continuación los nombres de los usuarios deseados separados por comas.
    • Para incluir todos los usuarios: «id:*»
    • Dejar la contraseña en blanco no guarda los cambios para ese campo.
    • Si queremos quitar la(s) contraseñas debemos usar la palabra clave «clear» solamente.
    • Evidentemente ningún usuario podrá llamarse «clear» (no hemos probado si admite tal usuario)-
    • Si queremos dejar sin contraseña, así esté establecida a nivel global usaremos «@nopass» solamente.
    • Si al contrario, solo queremos que nosotros como administrador seamos los únicos con derechos sobre una página o grupo de páginas usaremos la palabra clave «@lock» solamente.
    • Si previamente aplicamos «clear» o «@nopass» podemos restaurar las contraseñas globales con las correspondientes a continuación: «@_site_edit«, «@_site_read» or «@_site_upload» (si este último está establecido).

Nosotros como administradores podemos…

  1. Establecer contraseñas globales para páginas y/o grupo de páginas que no tengan contraseñas.
  2. Usar attr para controlar quien es capaz de establecer contraseñas en las páginas.
  3. Si está habilitada las subida de archivos, establecer contraseñas para ello.
  4. Usar nuestra contraseña de administrador para eliminar o cambiar las contraseñas de lectura y/o escritura establecidas para cada página o grupo de páginas.
  5. Usar «SiteAdmin.AuthList» para visualizar las páginas o grupos de páginas que tengan contraseñas establecidas.

Jerarquía de contraseñas.

  • Las contraseñas de páginas privan sobre las contraseñas de grupos de páginas.
  • Las contraseñas de grupos de páginas privan sobre las contraseñas globales.
  • Las contraseñas de administrador privan sobre las contraseñas globales, contraseñas de grupos de páginas y contraseñas de páginas.

Tapando los agujeros de orden y seguridad.

  • Por  defecto cuando editamos una página es opcional el colocar nuestro nombres para indicar autoría, esto es especialmente útil si nuestra wiki está abierta a todo público, completamente libre. Pero si estamos en el punto de haber creado cuentas de usuario debemos obligar a que utilizen su nombre en cada edición, esto se logra en el archivo config.php:
    • $Author = $AuthId; # after include_once()
  • También podemos permitir al usuario escribir el nombre que desee pero siempre aparecerá primero un prefijo que lo identifica como autor. Esto es útil si el autor desea compartir su clave con otro autor que nosotros no hemos autorizado y se desea saber quien hizo qué. En todo caso el autor/usuario con la cual se modificó la página o grupo de páginas será plenamente responsable de dichos cambios, sin importar si otra persona lo hizo.
  • Otra forma más estricta es inhabilitar el campo «autor» en el formulario de edición de cada página, pero eso cierra la posibilidad de dejar abiertas ciertas páginas o grupos de páginas (partiendo del principio de que cada quien desea ser conocido por los cambios realizados).
  • Si tenemos varias wikis corriendo en un mismo servidor (diferentes dominios o subdominios) debemos decirle a PHP que cada wiki tiene su propia y particular sesión agregando al principio de config.php la siguiente línea (por supuesto, generad vuestr propia clave aleatoria, y una por cada wiki que tengáis):
    • session_name('XYZSESSID');
  • Podemos establecer varias contraseñas para ‘admin’ con array() en el archivo config.php recordando el habilitar cuentas de usuario y contraseñas, forzando el grabado de autorías (ver párrafos anteriores) para saber quién hizo qué.
  • Podemos predefinir los grupos de páginas que contendrá nuestra PmWiki (más bien muchos verán esto como una restricción pero todo está en el diálogo entre los autores) por medio de insertar en config.php la siguiente clave: «$GroupPattern = ‘(?:Sitio|PmWiki|Principal|Ventas|Compras)’;» y si necesitamos ampliarla pues le agregamos otro caracter tubería seguido de los nuevos grupos.

Manejando la «internacionalizaciones».

Las llamadas «internacionalizaciones» («i18s«por su abreviatura en inglés de las 18 letras -22 en castellano-) son las traducciones a otros idiomas de PmWiki. Como bien sabemos el lenguaje PHP fue escrito en idioma inglés y PmWiki no es la excepción. La solución que planteó el Dr. Patrick Michaud está plasmada en dos aspectos fundamentales: la traducción de los «diálogos comunes» y la creación por parte de la comunidad de las respectivas páginas «tutoriales» que describen la instalación, uso y mantenimiento de PmWiki. Por ello divideremos esta sección en dos temas «apartes».

Traducción de los «diálogos comunes».

En PmWiki «normalizaron» los diálogos comunes, que son las instrucciones que visualiza el usuario. Las más visibles de ellas son «View Edit History Print Backlinks» que vemos en la parte superior derecha de cada página. El mecanismo es el siguiente: existe un archivo principal, el núcleo o corazón de PmWiki llamado «pmwiki.php» el cual nuestro servidor web ejecuta y carga los diversos componentes -que no vienen al caso por la complejidad del asunto-.

Lo que queremos ejemplarizar es cuando se carga el archivo «Site.PageActions» en la carpeta wililib.d allí tenemos unos cuantos mensajes al usuario, uno de ellos un enlace para modificar la página que esté en ese momento visualizando, otro para ver su historial además de las paǵinas relacionadas (y hay más enlaces/opciones).

En forma de matriz llamada text() se cargan los diferentes mensajes predefinidos por una estructura (de nuevo, estamos simplifanco al máximo) hasta llegar a los simples mensajes que acompañan una «acción», cargar pmwiki.php más el parámetro a ejecutar (cuando el usuario hace click en la opción/enlace correspondiente):

  • «Edit» -> «pmwiki.php?action=edit«
  • «History» -> «pmwiki.php?action=diff«
  • «Backlinks» -> «pmwiki.php?action=search&q=link={*$FullName}» (donde $FullName es una variable: el nombre de la página que estamos visualizando y sus páginas relacionadas -no existen jerarquías en PmWiki, solo existe en nuestros cerebros-)
PmWiki Site.PageActions
PmWiki Site.PageActions

Aquí es que vamos a llegar al meollo del asunto: dichas palabras «Edit», «History» y «Backlinks» aparecen  en el código no como texto en sí, sino como «variables»: «$[Edit]», «$[History]» y «$[Backlinks]» de manera tal que esas variables definidas se puedan especificar en un archivo con la extensión «.XLPage» con el siguiente contenido según nuestros ejemplos seleccionados:

  • ‘Edit’ => ‘Editar’
  • ‘History’ => ‘Historial’
  • ‘Backlinks’ => ‘Retroenlaces’

Resulta ser que para nosotros en supuesto «idioma español» nos asignaron dos letras «Es» de esta manera nuestro idioma vienen ser definidos los mensajes comunes en un archivo llamado «PmWikiEs.XLPage«. Pensamos que deberíamos diferenciarnos porque en España se hablan varioas idiomas: gallego, castellano, catalán, vasco y portugués… que está bien, Portugal se independizó y cogió otro rumbo y otro idioma pero forma parte de lo que los romanos al civilizar llamaron «Hipania» (perdón por la lección de historia, je, je, je). Somos de la idea de que deberíamos tener OTRAS letras como, se nos ocurre «cas» (ya «ca» está tomado por el idioma catalán) pero en fin, todos llevamos dentro nuestro pequeño «Don Quijote de la Mancha» y en cada molino vemos fieros gigantes ¡ja!

Traducción de las páginas en sí.

Al abrir la página principal de PmWiki sin haberla internacionalizado (a eso vamos) en el panel izquierdo («slide panel») aparecerá varias opciones -en inglés- de las cuales las tres primeras (hay site opciones en esa sección) dirán:

  • «Initial Setup Tasks»
  • «Basic Editing»
  • «Documentation Index».

Si colocamos el puntero sobre ellas, sin hacer click, veremos que sus enlaces web (llamados a pmwiki.php acompañados de un parámetro) serán los siguientes -coloreamos para que veáis las diferencias, no colocamos el enlace completo porque cada dominio web es diferente-:

  • pmwiki.php?n=PmWiki.InitialSetupTasks
  • pmwiki.php?n=PmWiki.BasicEditing
  • pmwiki.php?n=PmWiki.DocumentationIndex

Lo coloreado en color marrón son «páginas del sistema» de PmWiki y son las que debemos traducir ¿recordáis las dos letras de código de nuestro idioma? Pues las debemos intercalar para que apunten a los archivos que vamos a descargar con las traducciones:

  • pmwiki.php?n=PmWikiEs.InitialSetupTasks
  • pmwiki.php?n=PmWikiEs.BasicEditing
  • pmwiki.php?n=PmWikiEs.DocumentationIndex

Del siguiente enlace podréis descargar los idiomas disponibles en incluso un «megapaquete» con todas las traducciones. Nosotros solo descargaremos el archivo «i18n-es.zip» el cual descomprimiremos y «subiremos» a nuestro servidor teniendo cuidado de darle los permisos de lectura necesarios y los ubicaremos todos en la carpeta wikilib.d

Activando el idioma deseado.

En este punto debemos editar de nuevo el dichoso fichero llamado «config.php» que está ubicado en la carpeta /local y modificar y adicionar las siguientes líneas:

include_once("scripts/xlpage-utf-8.php"); # optional
XLPage('es','PmWikiEs.XLPage');

La primera línea en realidad la descomentamos porque viene así de la plantilla por defecto, y ese comentario que indica «optional» osea opcional para nosotros es obligatorio (ya eso lo explicamos en nuestro tutorial HTML). La segunda línea indica el llamar a la función XLPage y tiene dos parámetros:

  • El primer parámetro son las letras que mostrará en el cintillo inferior en el caso que instalemos varios idiomas, no tiene nada que ver con la codificación ISO de dos letras. Por razones estéticas y debido a la cantidad de idiomas y que ninguno destque de los demás se escoge ese formato pero nada nos impide colocarle «español» o «castellano»; queda a vuestro criterio -si manejais pocos idiomas-.
  • El segundo parámetro es el nombre exacto del archivo porque los servidores GNU/Linux distinguen mayúsculas de minúsculas. Aquí queda de parte de nosotros mantener la clave ISO «Es» para claridad de nuestros archivos, debemos ser conscuentes en esto porque nuestros grupos de páginas llevarán siempre el perfijo PmWikiEs.

Mejorando la selección de idioma.

No sabemos quien visitará nuestra página en este mundo tan globalizado, pero si utilizan un navegador web que se haya programado según las normas del W3C lo mejor que podemos hacer es incluir en config.php el siguiente guion:

[cc lang=»php» tab_size=»2″ lines=»40″]$lang = substr($_SERVER[‘HTTP_ACCEPT_LANGUAGE’], 0, 2);
switch ($lang){
case «es»:
XLPage(‘es’,’PmWikiEs.XLPage’);
break;
case «en»:
XLPage(‘en’,’PmWikiEn.XLPage’);
break;
default:
XLPage(‘en’,’PmWikiEn.XLPage’);
break;
}[/cc]

En la primera línea por medio de PHP le preguntamos al servidor web el encabezado con que solicita la página nuestro visitante y extraemos las dos primeras letras para luego seleccionar de los idiomas disponibles que tengamos instalados, y por defecto, si no se consigue, pues lo mostramos en ingéls, el lenguaje «materno» de PmWiki. Lo hemos probado con Mozilla Firefox 53 y funciona.

Actualizado el sábado 5 de mayo de 2018

PMWiki funciona como la Wikipedia, está abierta para que todos y todas coloquemos nuestras sugerencias y propuestas. Por ello el 13 de junio de 2017 propusimos en la página oficial del Proyecto PMWiki el código anterior y a la fecha de hoy la propuesta se mantiene, ergo, no la han eliminado y suponemos que ya con tanto tiempo transcurrido queda aprobada de manera implícita. Dicha propuesta la pueden consultar en este enlace y si aun dudaís de nuestra autoría basta conq ue hagáis click en el historial del artículo. Fue un honor haber contribuido en algo al tema.

Visualizando por primera vez nuestra página en nuestro idioma.

Pues tan simple como recargar la página y los mensajes comunes estarán en nuestro idioma… pero hasta allí llega nuestra «alegría de tísico» (por lo poco que dura antes de entrar en un atque de tos). Resulta que igual nos aparece en inglés todo lo demás y he aquí que debemos comenzar a trabajar.

PmWiki página principal por defecto -idioma español establecido-
PmWiki página principal por defecto -idioma español establecido-

La primera página que modificaremos es precisamente la principal llamada «Main.HomePage» la cual, por ahora, no hemos encontrado manera de cambiar al castellano. Lo que es cierto es que podemos -y debemos- modificarla borrando todo el contenido en inglés e ir creando nuestro propio contenido para luego modificar el panel izquierdo («edit SideBar»).

Nuestro primer grupo de páginas.

Aunque suene extraño vamos a aventurarnos a crear dos grupos de páginas de una vez. Para ello ya estamos modificando la «Main.HomePage» (luego de haber introducido nuestra contraseñade edición, si la hubiéramos establecido) y escibiremos el siguiente código:

[[WikiAeroplanos | Aviones]]
* [[WikiAeroplanos.Cazas | Uso militar]]
* [[WikiAeroplanos.Pasajeros | Transporte]]
* [[WikiAeroplanos.Hidroaviones | Mixto]]

[[WikiTrenes | Trenes]]
* [[WikiTrenes.Electricos | Siglo XXI]]
* [[WikiTrenes.Vapor | Siglo XX]]

Le damos guardar y al recargar la ápgina veremos lo siguiente:

PmWiki creando grupos de páginas
PmWiki creando grupos de páginas

¿Observáis los signos de interrogación que nosotros no escribimos? Pues es la maner de PmWiki indicarnos que dicho tema no ha sido escrito. Aquí radica la sencillez y rapidez de PmWiki: cuando hacemos click se abre inmediatamente para editar cada una de las págins que queremos desarrollar. He aquí que le vamos agregar un poco de complejidad a cada una de ellas.

Fuentes consultadas.

En idioma francés.

En idioma inglés.

Download PDF
GNU Linux Debian Cloud

Debian 8.8 AMD64 primer vistazo

Download PDF

Utilizamos VirtualBox sobre Ubuntu 16, una distribución «hija» de Debian, la «madre» de todas las distribuciones GNU/Linux (o al menos una de las más importantes). Son 3 DVD’s de los cuales usamos el número uno para una instalación básica, sin mayores pretensiones, para realizar nuestras pruebas de programación. Es bien conocido que con VirtualBox podemos crear imágenes estáticas del ordenador virtual y hacer nuestras prueba para luego restaurar a sus estado original, esto es muyt útil para nosotros. Escogimos, como siempre, a Youtube con ángel custodio del vídeo de instalación, esperamos os sea de provecho la información contenida.

Requisitos mínimos de instalación:

Una vez que haya reunido información sobre el hardware de su ordenador debe verificar que su hardware le permita realizar el tipo de instalación que desea efectuar. Dependiendo de sus necesidades, podría arreglarse con menos del hardware recomendado listado en la siguiente tabla. Sin embargo, la mayoría de usuarios se arriesgan a terminar frustrados si ignoran estas sugerencias.

Se recomienda como mínimo un Pentium 4, a 1 GHz para un sistema de escritorio.

Tipo de instalaciónRAM (mínimo)RAM (recomendado)Disco duro
Sin escritorio128 Megabytes512 Megabytes2 Gigabytes
Con escritorio256 Megabytes1 Gigabyte10 Gigabyte

Los requisitos de memoria mínimos necesarios son en realidad inferiores a los indicados en esta tabla. En función de la arquitectura, es posible instalar Debian en sistemas con tan sólo 20 MB (en el caso de s390) a 60 MB (para amd64). Lo mismo se puede decir del espacio necesario en disco, especialmente si escoge las aplicaciones que va a instalar manualmente, consulte Sección D.2, “Espacio en disco requerido para las tareas” para obtener más información de los requisitos de disco.

Es posible ejecutar un entorno de escritorio gráfico en sistemas antiguos o de gama baja. En este caso es recomendable instalar un gestor de ventanas que es consuma menos recursos que los utilizados en los entornos de escritorio de GNOME o KDE. Algunas alternativas para estos casos son xfce4, icewm y wmaker, aunque hay más entre los que puede elegir.

Es prácticamente imposible dar requisitos generales de memoria y espacio en disco para instalaciones de servidores ya que éstos dependerán en gran medida de aquello para lo que se utilice el servidor.

Recuerde que estos tamaños no incluyen todos los otros materiales que se encuentran habitualmente, como puedan ser los ficheros de usuarios, el correo y otros datos. Siempre es mejor ser generoso cuando uno está pensando qué espacio destinar a sus propios ficheros y datos.

Se ha tenido en cuenta el espacio de disco necesario para la operación normal del sistema Debian GNU/Linux en sí en estos requisitos de sistema recomendados. En particular, la partición /var de Debian contiene mucha información de estado específica a Debian, además de su contenido habitual, como puedan ser los ficheros de registro. Los ficheros de dpkg (que incluyen información sobre los paquetes instalados) pueden fácilmente consumir unos 40 MB. Además, hay que tener en cuenta que apt-get ubica los paquetes descargados aquí antes de instalarlos. Por regla general deberá asignar por lo menos 200 MB para /var, y mucho más si va a instalar un entorno gráfico de escritorio.

 

Fuentes consultadas.

 

Download PDF

PTT: Python Twitter Tools by Mike Verdone

Download PDF

Desde hace tiempo venimos utilizando nuestro propio robot (o «bot» como es la moda ahora mentarlos) para promocionar esta nuestra y vuestra humilde página web por Twitter y la verdad es que no habíamos prestado mayor atención al trabajo hecho con la librería que permite hacerlo. Utilizamos Twitter por su simplicidad y el soporte que tenía por medio de mensajes de texto «Short Message Service SMS«a los móviles celulares: sencillo y elegante. Pero mejor estructuremos esta entrada para explicaros (y compartir) nuestro conocimento acerca del tema ¡Vengan con nosotros en este nuevo registro en la bitácora!

Breve historia del Twitter.

Que no os vamos a aburrir mucho con esto, pero por algo se empieza. Como preludio consideramos justo reconocer que los creadores de Twitter debe haberse inspirado en algún momento en el famoso protocolo de comunicaciones llamado «Internet Relay Chat IRC» el cual fue creado en 1988 por Jarkko Oikarinen y que tuvo su apogeo en el año 2004 con el popular juego de acción QuakeNet (240 mil usuarios -solo esa red, a nivel mundial hay muchas otras redes de usuarios-). Desde ese año el IRC ha ido declinando en el número de usuarios y llegado el año 2006 Jack Dorsey, Noah Glass, Biz Stone y Evan Williams fundan Twitter y en seis años consiguen 100 millones de usuarios que «tuiteaban» 340 millones de mensajes diarios. Inicialmente no fue pensada como una red social sino como un blog que utilizaría los mensajes de texto por teléfono móvil y debido a su limitación de 140 caracteres se convirtió de facto en un microblogging.

Nosotros usamos Twitter desde el año 2011, justo un año después de haber comenzado a utilizar la tecnología OAuth -desarrollada en las entrañas de Twitter desde el mismo año de su nacimiento en el 2006- para ganar seguridad y libertad de programación a aplicaciones de terceros con una «Application Programming Interface API«. Acá en Venezuela el operador Movistar (antes conocida como Telcel) daba soporte para enviar mensajes al Twitter por medio de mensajes de texto al número 89338 (TWEET) y funcionaba de maravillas pero actualmente no prestan el servicio, imaginamos que por falta de arreglo económico entre ambas empresas, recordad que nadie trabaja gratis (sin embargo se ganan una buena pasta vendiendonos megabytes de datos que usamos en Twitter). Otro aspecto del impacto de Twitter en nuestra vida diaria es la inclusión del verbo «tuitear» en el Diccionario Castellano de la Real Academia Española así que si en adelante no lo incluimos entre comillas pues ya veis que es «legal» usarlo así ya que es un anglicismo formalmente reconocido (¡qué fuertes son los Poderes Fácticos del siglo XXI!).

Para aquellos que queréis saber más de la historia y funcionamiento del Twitter -en inglés, publicado en el año 2016 por Amelia Norton y creado por Andreas Schreiber en 2009- navegad hasta este sitio donde publica unas diapositivas digitales donde la primera mitad explica todo esto y más adelante entra en materia más profunda; está profusamente ilustrado y va paso a paso:

¿Que cómo era el Twitter antes del OAuth? Podéis leer este artículo publicado en el año 2009 donde dan cuenta de como «tuitear» por medio del comando curl:

curl -u usuario:contraseña -d status="Tu mensaje" http://twitter.com/statuses/update.xml

¡Increíble! Fijaos que Twitter ni siquiera era una página segura (https) y el usuario y contraseña viajaban libres por la red ¡eran otros tiempos, éramos más confiados (y con menos preocupaciones)! (Gracias Nacho por tu explicación, como veís 8 años después tus palabras aún resuenan en el ciberespacio). Acá otro artículo comentan como, incluso, como «tuitear» con PHP y curl y analizar la respuesta en formato tanto en formato XML como JSON.

Pero he aquí que ya el Sr. Nacho explicaba como utilizar el lenguaje Python con las librerías del sr. Mike Verdone creador de la «Python Twitter Tools PTT«, un software de código abierto y apoyado plenamente por la Fundación Python, y éste es el artículo principal de esta entrada.

«Python Twitter Tools PTT» por Mike Verdone.

Funcionamiento básico de la red Twitter.

Twitter siempre ha utilizado el software libre para lograr sus propósitos y en un principio utilizaba MySql como manejador de base de datos, pero pronto le quedó pequeña para sus propósitos.

Lo que aquí expresamos es a grandes rasgos, no esperéis una explicación al detal de la tecnología usada por Twitter; lo expresamos a nuestra forma y entendimiento y lo plasmamos de la manera más simple posible y si cometemos algún error hacednolos saber por nuestra cuenta Twitter @ks7000.

Ahora Twitter utiliza Ruby on Rails en servidores Java con «Content Delivery Network CDN» distribuidos en todo el mundo y cada identificador de mensaje es único y tiene información acerca de su geolocalización para poder manejar la gran cantidad de información que se genera segundo a segundo. En el acortador de direcciones ubicado en http://t.co aparte de ahorrar espacio en los mensajes también revisa y detiene los enlaces maliciosos (páginas falsas, páginas con código dañino, etc) y en el servicio https://twimg.com/ permite almacenar las imágenes que acompañan el mensaje. También han incluido soporte para emoticons que en realidad es soporte para todos los caracteres que soporta el UNICODE, así como soporte para «gifs animados» (que en realidad son convertidos a formato MP4), así como transmisión de vídeo en vivo por Periscope y a futuro vienen muchos cambios más para mantener con vida esta red. Uno de los más redituables son los «Twitter Ads» que es publicidad personalizada ¡repetimos, nadie trabaja gratis!

Twitter y el software desarrollado por terceros.

El equipo de Twitter creó y desarrolló de manera abierta la tecnología OAuth para que aplicaciones de terceros puedan acceder a ciertas características de nuestra cuenta en Twitter sin necesidad de darle nuestra contraseña de cuenta. Esto se logra de la siguiente manera:

  • Un equipo de desarrolladores se unen y crean una cuenta en Twitter. Deben colocar, al menos, un número de teléfono celular para recibir por mensaje de texto la confirmación de apertura de la cuenta deseada, así es que al menos es una persona real a quien le pertenece el número telefónico y es responsable de dicha cuenta.
  • Si es un proyecto muy grande el siguiente paso más probable es que contacten a Twitter -en San Francisco si viven y trabajan en los Estados Unidos de América o en Dublín, Irlanda, para el resto de los países del mundo- para solicitar una cuenta verificada (las cuentas que son identificadas con un símbolo azul y tooltip que las anuncia). Twitter recomienda que para proyectos pequeños -que por supuesto tienen su propio dominio web- publiquen en su página web la cuenta twitter oficial -tal como nosotros hacemos acá-. Esta norma rige también para personalidades, artistas, políticos, páginas de los gobiernos, etc.
  • Una vez hayan configurado sus datos en Twitter hay un apartado que permite crear dos token llamados “Consumer Key” (Clave de Consumidor) y “Consumer Secret” (Secreto de Consumidor) que deben ser almacenados de forma segura por los desarrolladores de la futura aplicación (en PTT está almacenada en donde alojan el código fuente, GitHub). Un token no es más que una larga secuencia alfanumérica de caracteres regidos por fórmulas matemáticas que permiten identificar de manera unívoca un objeto de software.
  • Una vez obtenida la Clave del Consumidor la aplicación debe proveer un enlace hacia Twitter con la siguiente orden:  «https://api.twitter.com/oauth/authorize?oauth_token=Consumer_Key». Si no hemos iniciado sesión en Twitter introduciremos nuestro usuario y contraseña la cual se la estamos entregando a Twitter por medio de una página web segura https, no a la aplicación en sí.
  • Una vez entramos en Twitter nos redirigirá a una página donde explica qué privilegios solicita la aplicación y y botón para aprobarla. Muy importante que leamos bien que derechos de acceso otorgamos, si estamos de acuerdo le damos aceptar.
  • Una vez que aprobamos Twitter genera a su vez otros dos token que son enviados a la aplicación que desea acceder a ciertos elementos de nuestra cuenta. Si la aplicación web está instalada en nuestro ordenador o dispositivo móvil por medio de un PIN que nos muestra Twitter por pantalla lo copiaremos y suministraremos a la aplicación para que ella obtenga por sus propios medios los dos token personalizados para nosotros y procederá a guardar en nuestra máquina. Si es una aplicación web se redirijirá la página y obtendrá ella misma los dos token necesarios.
  • El punto anterior funciona de dos maneras diferentes: en la aplicación instalada en nuestro ordenador o celular los token se almacenarán en nuestros equipos. Si es una aplicación web los token se almacenarán en el o los servidores de la aplicación. En el primer caso nosotros usaremos los 2 token personalizados -público y privado-, en el segundo caso será la aplicación de manera autónoma quien los usará -y nosotros nunca sabremos los valores de los token generados, a diferencia del primer método-.
  • En cualquier momento podemos eliminar el acceso a la aplicación si nos dirigimos a «https://twitter.com/settings/applications» y pulsamos el botón de revocar: esto simplemente hace que Twitter inactive los dos token que generamos y así negará el acceso a las partes de nuestra cuenta que habíamos autorizado.
  • Las partes de nuestras cuentas que podemos otorgar acceso son las siguientes (caso PTT):
    • Acceder a nuestra línea de tiempo (los tuits de las cuentas que seguimos).
    • Enviar mensajes públicos y/o privados con nuestra cuenta.
    • Permitir leer nuestros datos: avatar, nombre e incluso nuestro correo electrónico.
    • Seguir y/o dejar de seguir otras cuentas en Twitter.
  • Se ha hecho ya costumbre el crear estas aplicaciones simplemente para permitirnos emitir comentarios en las páginas web o por medio de varias páginas web que se afilien a esa aplicación: Disqus es un buen ejemplo de ello, son aplicaciones con una API basadas a su vez en las herramienta API de Twitter con el esquema de autorización OAuth.
  • Aunque logren acceder a nuestro ordenador o si nos roban o se pierde nuestro teléfono celular siempre podemos iniciar sesión en Twitter en cualquier otro equipo confiable y revocar el acceso a dichas aplicaciones: eso inutiliza los token personalizados que fueron generados.
  • De igual manera si el sitio que aloja la aplicación web que autorizamos les roban dichos token personalizados hacemos lo mismo del punto anterior. Un ejemplo de pérdida de datos fue lo sucedido con TweetGif.

Instalando PTT.

Ya hemos publicado como instalar el lenguaje Python en nuestras máquinas, así que aquí solo escribiremos como instalar las utilerías desarrolladas por el sr. Mike Verdone. Debemos entonces referiros a otro de nuestros posts donde explicamos la clasificación de las funciones en Python: las que provienen de terceros deben instalarse con PIP. Hacemos notar por experiencia propia que GNU/Linux Debian Jessie 8.8 no trae instalado por defecto el pip. No hay problema, lo que debemos hacer es escribir -con derechos de administrador root ganados con su-:

apt-get install python-pip

Tras lo cual no solicitará que introduzcamos el DVD N° 1 (el 2° y el 3° contienen aún mucho más software pero menos utilizados) por lo que nos ahorramos el conectarnos a internet (por eso decimos que viene «instalado por defecto» en las distribuciones GNU/Linux). Una vez tengamos instalado el pip debemos lanzar la siguiente instrucción:

sudo -H pip install twitter

El parámetro -H en sudo (o, si gustan, –set-home) especifica que la política de seguridad sea fijada en el usuario actual que ejecuta el comando a efectos de registrar una entrada en la base de datos de contraseñas del usuario, aunque es la opción por defecto hay que recalcarsela cuando instalemos cualquier otro paquete con PIP. Acá podéis ver el resultado del comando, nos instala la última versión disponible a la fecha, la 1.17.1:

sudo -H pip install twitter
sudo -H pip install twitter

Comentarios de Mike Verdone sobre la versión 1.9.1

En enero de 2013 anunció la liberación de la versión 1.9.1 con las nuevas características para el momento pero lo que nos llamó la atención fue el siguiente comentario en el último párrafo en su blog:

At this point I rarely do dev work on Python Twitter Tools. I merely evaluate and merge the pull requests submitted by other talented developers. A great big thank you to all of them! Their names reside safely in the Git project history, for all eternity.

Que traducido al castellano sería más o menos lo siguiente:

En este momento raramente desarrollo trabajo en «Python Twitter Tools». Yo simplemente evaluo y uno las propuestas enviadas por otros talentosos programadores. ¡Un grandioso agradecimiento a todos y cada uno de ustedes! Sus nombres reposarán de forma segura en la historia del proyecto (en formato Git), por toda la eternidad.

Esto, para nosotros, es poesía para nuestros oídos y una muy buena apología al Software Libre, ¡Libertad!

Configurando PTT por primera vez.

El Python Twitter Tools viene conformado por dos componentes: las librerías en si mismas -que podremos usar si tenemos nuestras propios token otrogados por Twitter a traves de nuestra cuenta allí creada- y un archivo ejecutable llamado twitter que podremos llamar por medio de una ventana terminal.

Primero explicaremos como usar el ejecutable compilado con ayuda los token pertenecientes a Mike Verdone, es decir, vamos a autorizar única y exclusivamente al programa twitter que instalamos por medio de PIP para que interactue con nuestra cuenta en Twitter.

twitter authorize
twitter authorize

Lanzamos una ventana terminal y escribimos simplemente «twitter authorize» lo cual hará que dicho software lance un navegador por el siguiente enlace:

Authorise Command-line Tool to use your account?
Authorise Command-line Tool to use your account?

Notad que la página web es segura, «candado verde» (si no hemos iniciado sesión e Twitter, pues ingresad y la página se redirige) y que nos explica brevemente que accederá a leer los tuits que publican a quienes seguimos -esto es conocido como línea de tiempo o «timeline» en inglés-, ver la lista de quienes seguimos -y el permiso de seguir nuevas cuentas-, actualizar nuestro perfil cosa que nos sorprende ya que no vemos opciones documentadas para hacer esto (cambiar nuestro nombre, avatar, etc) lo cual investigaremos en detalle para qué quiere tener acceso a este renglón, y por último la habilidad de tuitear por nosotros de una manera automatizada (vamos a comenzar por esto último, enviar un mensaje al ciberespacio).

Una vez hallamos autorizado a la aplicación en la página del Twitter nos mostrará un PIN el cual fue pensado para aplicaciones que no tienen una interfaz web -léase aplicaciones de líneas de comandos- al cual el PTT llama con un argumento distinto al comando oauth_callback (toma el valor oob «out-of-band»). Dicho PIN debemos introducirlo en la entrada que requiere PTT tras lo cual se comunicará -vía curl, imaginamos con Twitter para obtener nuestros token personalizados que serán almacenados en la siguiente ubicación: ~/.twitter_oauth (un archivo oculto en nuestra carpeta personal «home»).

Una vez hallamos configurado adecuadamente la aplicación, no tenemos mas que escribir nuestro primer mensaje por medio de PTT: «twitter set» tras lo cual pedirá que ingresemos nuestro mensaje, presionamos intro y listo, se fue al universo del microblogging nuestra prueba:

Usando PTT (agradecimiento incluido):

Este mensaje lo enviamos el día 20 de mayo de 2017, cuando publicamos esta entrada (nosotros publicamos cuando consideramos tenemos algo suficientemente redactado, luego lo refinamos y con el paso del tiempo lo mantenemos actualizadas cada una de nuestras entradas en nuestro blog). En ese mensaje recibimos un «me gusta» por parte del usuario @sixohsix (ya comentamos que toda aplicación web de Twitter debe tener, por supuesto, una cuenta en Twitter).

Revisando cada una de las acciones de PTT.

Seguimos revisando la aplicación compilada twitter por la línea de comando, luego veremos el uso de las utilerías y programaremos. Para PTT es necesario tener instalado argparseque ya os hemos explicado como funciona– y es la que permite introducir «twitter -h» para saber sus acciones y preferencias. De número uno la opción por defecto es la que estudiaremos.

«twitter» ó «twitter friends».

Al escribir «twitter» estamos invocando en realidad «twitter friends«: esto devuelve por pantalla los mensajes o tuits -incluyendo los retuits- de las cuenta a las cuales seguimos. Recordad que vuestra velocidad de conexión al internet influirá en la respuesta, paciencia que puede tomar cierto tiempo.

Como nosotros vamos de programación, y por ende de tareas automatizadas, el primer uso que le vamos a dar es filtrar resultados con grep mediante el comando tubería. Lo que vamos a buscar son los tuits que contengan la palabra -valga la publicidad- «Samsung» utilizando la salida stdout al comando de filtrado grep de la siguiente manera:

twitter friend | grep "Samsung"
twitter friends | grep «Samsung»

Primero notad que debemos acostumbrarnos a entrecomillar siempre la clave a buscar ya que Twitter utiliza etiquetas cuyo prefijo es el caracter numeral «#» el cual significa comentario en el shell bash.

«twitter help» ó «twitter -h».

Por supuesto esta opción es insoslayable: retribuye las opciones documentadas o declaradas (como tenemos acceso al código fuente podremos estudiar y buscar opciones no documentadas debidamente).

«twitter follow» y «twitter leave».

Recordemos que le dimos permiso a la aplicación de seguir o dejar de seguir otra cuenta en Twitter, así que para seguir una cuenta escribimos «twitter follow @nombre_de_la_cuenta» y para dejar de seguirla «twitter leave @nombre_de_la_cuenta«. Nosotros la probamos con @cementerio una cuenta argentina que se dedica a emitir día a día el fallecimiento tanto de personajes famosos a nivel mundial como a nivel local, mirad la imagen:

twitter follow y twitter leave
twitter follow y twitter leave

«twitter list» y «twitter mylist».

Una lista en Twitter simplemente es un conjunto de cuentas que agrupamos según un criterio definido, en nuestro caso clasificamos a los desarrolladores de software por cada país del mundo. Las listas pueden ser públicas como privadas así que si vemos alguna cuenta que NO sigue a nadie no necesariamente quiere decir que sea una cuenta inactiva, tal vez tenga una lista privada para recibir información de manera discreta. Con «twitter list @nombre_de_usuario» podremos obtener los nombres de las listas públicas de un usuario de Twitter, lo estemos siguiendo o no (por supuesto, si no lo seguimos y su perfil es público). De lo contrario, si la cuenta está «protegida» (perfil privado) devolverá el error 34 con el mensaje «‘Sorry, that page does not exist.«; esto es así por la máxima privacidad al usuario: cuando le preguntamos al Twitter éste lo niega, incluso su existencia (es decir, no anuncia que la cuenta es privada). De esta opción hicimos pruebas pero no publicamos las cuentas protegidas que consultamos para conservar la privacidad pero hemos de deciros que funciona a la perfección (si acaso podríamos hacer un «fork» para el tratamiento de mensajes de error, -vamos a ver hasta dónde llegamos-). Con la opción mylist y como son nuestras propias listas, obtendremos tanto listas públicas como privadas.

«twitter replies».

Con este comando nos retribuye las últimas respuestas a nuestros tuits -primero los más antiguos-, valga decir que son mensajes que se hilan en una nueva conversación o en una existente. En Twitter esto es como un árbol con la raíz invertida: si solo son dos usuarios es una linea directa de conversación pero si varios usuarios intervienen entonces se convierte en un árbol. Es de notar, por supuesto, que si uno opta por silenciar «mute» una conversación, ya no recibiremos aviso alguno de la misma.

«twitter search».

Al nosotros utilizar esta opción de inmediato nos devolvió error (y no, no es por incluir el «octothorpe» o símbolo numeral que tiene un signficado especial en Python). El error está «denunciado» en este enlace y en la medida de lo posible estamos revisando el código para ver si podemos ayudar en algo.

«twitter shell».

Todos los argumentos que acabamos de ver los ejecutamos directamente de la consola de nuestra distribución GNU/Linux pero si usamos «twitter.shell» entraremos en el prompt del propio PTT: así podremos escribir «set ‘mensaje'», presionar intro y enviamos nuestro mensaje. Es decir, nos ahorramos la palabra «twitter» en cada llamado.

twitter shell
twitter shell

Para salir del shell del PTT solo debemos pulsar la tecla CTRL+D tras lo cual preguntará la aplicación «You really want to Leave (Y/n)? » y pulsamos la tecla «Y», presionamos intro y «salimos» al shell de nuestro ordenador.

«twitter rate».

Así como hay un límite máximo de 100 tuits por hora para cada cuenta en Twitter (si emitimos 100 tuits en 100 segundos -un minuto y cuarenta segundos- estaremos bloqueados por una hora más o menos) también hay unos límites en las tareas automatizadas. Cada límite está establecido para cada uno de los métodos establecidos en la API y sería largo de enumerar aquí; algo relevante es que dichos valores se «reinician» cada 900 segundos, osea cada 30 minutos. Como veís, es muy similar al límite que comentamos al principio, solo que el bloqueo dura media hora en vez de una hora completa.

«twitter repl».

Con este comando entraremos en una ventana normal de Python pero con un mensaje de bienvenida que es más que elocuente:

twitter repl
twitter repl

En el anuncio nos indica que por medio del objeto «twitter» (declarado y conectado por un script o guion previo) podremos interactuar con la REST API lo cual consideramos algo avanzado y creemos con propósitos de depuración a bajo nivel. Para salir usamos CTRL+D, recuerden que estamos en Python terminal. Por ahora no le encotramos mayor utilidad y lo dejamos tranquilo para pasar al otro comando que nos parece tremendamente útil.

«twitter pyprompt»

Esto si lo consideramos muy útil y sirve como paso previo antes de comenzar nuestros ejemplos y pruebas con las librerías en sí mismas: si con twitter shell podemos escribir solo los comandos (set, rate, etc.) con este comando tendremos un objeto «twitter» declarado y conectado con el cual podremos programar aspectos más vanzados, como por ejemplo tuitear incluyendo imágenes. La diferencia principal es que estaremos conectados con los token que autorizamos (¿recuerda «twitter authorize»?) y podemos programar a nuestras anchas, en cambio al lanzar Pythom e importar la librería debemos nosotros mismos sumistrar los 4 elementos completos:

  • token (del lado de la aplicación registrada en Twitter).
  • token_secret (del lado de la aplicación registrada en Twitter ¡estricto cuidado NO difundir!).
  • consumer_key (del lado nuestro, los token que solicitamos y autorizamos).
  • consumer_secret (del lado nuestro, los token que solicitamos y autorizamos ¡estricto cuidado NO difundir!).

Si a la final metemos la pata y hacemos pública nuestro token privado de cliente, pues iniciamos sesión en Twitter y revocamos el acceso a la aplicación. Si somos desarrolladores y hacemos pública nuestro token privado de aplicación (tal como hizo PTT) pues vamos con la cuenta twitter con que creamos la aplicación y le revocamos el acceso. Como veís la seguridad está en parte garantizada y Twitter feliz de la vida delegando esas responsabilidades en nosotros: ellos ponen la maquinaria, nosotros la mano de obra.

Preferencias u opciones de PTT.

De las acciones que estudiamos anteriormente, estas preferencias son compatibles con todas ellas, comenzemos por «–refresh».

Opción «-r» ó «–refresh».

Cuando utilizamos el comando grep para filtrar resultados -de una manera «rudimentaria» bien pensamos agregar el comando al crontab de nuestro sistema GNU/Linux pero no es necesario llegar a tanto. Para ello contamos con la opción «-r» ó «–refresh» para que el comando que corriendo indefinidamente hasta que presiones CTRL+C para interrumpir el proceso. De manera predeterminada el intervalo es de 5 minutos (300 segundos) pero con la opción «-R» ó «–refresh-rate» podemos especificarle un valor en segundos que querramos -e incluso programar para que sea un valor aleatorio-. De las pruebas que hicimos nos dimos cuenta que valores inferiores a 60 segundos devuelve error el Twitter: recordad que no debemos sobrecargar a los servidores de dicha empresa con solicitudes tan frecuentes.

twitter friends --refresh
twitter friends –refresh

Opción «-l» ó «–length».

Otro valor por defecto es el número de mensajes retribuidos, el valor normal es 20 pero podemos pedir uno solo o el que queramos pero con un maximo de 200 mensajes o tuits. Como por consola es difícil ver dónde termina y dónde comienza cada mensaje la siguiente opción nos permitirá contar de lo lindo el número de tuits retribuidos a ver si es verda que se ejecuta tal como lo pedimos.

Opciones «-t» ó «–timestamp» y «-d» ó «–datestamp».

Con estas opciones podremos colocar tanto la hora y minuto como la fecha de cada mensaje, algo útil si queremos guardar los datos en una tabla de base dedatos y ordenarlos luego de forma cronológica. Atención: la hora y fecha de cada mensaje es, por supuesto, cuando lo emitieron originalmente pero cuando alguien a quien nosotros seguimos lo retuitea -o reenvía- nos mostrará fecha y hora del retuiteo, no de la hora y fecha original.

Opción «–no-ssl».

Esta opción de facto está eliminada: toda transacción hoy en día con los servidores de la empresa Twitter solamente están disponibles en formato segor https: toda nuestra información viaja cifrada entre nosotros y Twitter.

Opción «c» ó «–config».

Si decidimos almacenar nuestro usuario y contraseña en un archivo con esta informacón la podemos cargar con esta opción. No se nos ocurre un uso práctico, sin contar que los datos, de manera implícita, estarán almacenadas en texto plano, un riesgo de seguridad para nosotros. Por esa razón es que dudamos -como dice la ayuda- que es para guardar usuario y contraseña. En más detalle indica que dicho archivo de configuración permite guardar consultas personalizadas siempre y cuando dentro del archivo tenga el encabezado «[twitter]» y a continuación en una línea que comienza con la etiqueta «format:» le colocamos las opciones que ya revisamos y en otra línea algo nuevo: un prompt personalizado en texto y colores. Esta opción es la más adecuada «para despertar al nerd que hay en tí» ja, ja, ja 😉 .

Opción «–oauth».

De igual manera que la anterior pero con nuestras propias crdenciales como es nuestro caso. os explicamos mejor, nosotros registramos una aplicación en Twitter que generó los cuatro tokens que explicamos párrafos atrás. Si los colocamos en un archivo ocn esta opción nos conectaremos por nuestra aplciación y no por la de PTT.

Opción «–format».

Si lo que queremos es ver nosotros mismos de una manera agradable por pantalla podemos optar entre los siguientes:

  • default: bueno, es como si no hubieramos escrito nada, una línea por mensaje.
  • verbose: múltiples líneas por mensaje.
  • json: devuelve los datos en este popular formato.
  • urls: si solamente queremos ver los enlaces (recordad que Twitter usa acortador de direcciones).
  • ansi: la mejor opción, colores a diestra y siniestra.

 

Licencia de uso de PTT.

Python Twitter Tools se rige por la Licencia del Instituto Tecnológico de Massachusetts (Massachusetts Institute of Technologies MIT) del año 2008 y donde aparece el sr. Mike Verdone como único propietario:

Copyright (c) 2008 Mike Verdone

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

La Licencia del MIT permite uso privado, modificación, distribución y uso comercial con la condición de que la licencia sea distribuida junto con los demás ficheros de la aplicación y la advertencia de que no se hacen responsables del mismo (en el software libre los únicos responsables somos nosotros mismos, esta parte de la licencia es muy dura de entender por los usuarios acostumbrados al software privativo).

Equipo de desarrollo de PTT.

He aquí una lista de las personas que participan -y mantienen al día- el proyecto «Python Twitter Tools» -una lista actualizada la podeis encontrar en este enlace en GitHub, al momento presente son los siguientes:

Developers:
Mike Verdone <mike.verdone@gmail.com>
Hatem Nassrat <hnassrat@gmail.com>
Wes Devauld <wes@devauld.ca>

Contributors:
Horacio Duran <horacio.duran@gmail.com> (utf-8 patch for IRC bot)
Rainer Michael Schmid (bugfix: crash when redirecting output to a file in 1.1)
Anders Sandvig (cmdline -l, -d, and -t flags)
Mark Hammond (OAuth support in API)
Prashant Pawar (IRC bot multi-channel support)
David Bittencourt (python 2.3 support)
Bryan Clark (HTTP encoding bugfix, improved exception logging)
Irfan Ahmad <http://twitter.com/erfaan> (Fixed #91 rate limit headers and #99 twitter API timeouts)
StalkR (archiver, follow)
Matthew Cengia <mattcen> (DM support, ISO timezone support, more API 1.1 support)
Andrew <adonoho> (Fixed streams support for HTTP1.1 chunked answers)
Benjamin Ooghe-Tabanou <RouxRC> (Helped fix streams support for HTTP1.1 chunked answers, added image support and more API 1.1 support)

Fuentes consultadas:

En castellano:

En idioma inglés:

Download PDF

PHP tutorial

Download PDF

Un lenguaje importante y que hemos dejado de lado por años es el ya muy famoso lenguaje PHP. En desagravio publicamos esta entrada y le queremos dar características especiales: no insisteremos en ser detallistas al extremo, se trata de una introducción, un tutorial que lleve paso por paso a cualquier persona que desee aprender dicho lenguaje de programación. Por ello no publicaremos su historia, configuración del servidor, etcétera. Os recordamos que para aprender PHP sería bueno tener conocimientos mínimos de HTML, CSS y JavaScript.

Seguir leyendo

Download PDF
@ObiJuan_cube

Bien merecido galardón O’Reilly para @ObiJuan_cube González

Download PDF

Cuando tuvimos que actualizar nuestros conocimientos sobre Diseño Asistido por Computadora (CAD) nuestra experiencia era limitada y amarrada al software privativo Autocad® y como estamos decididos a ser libres nos decantamos por Freecad para realizar nuestro trabajo. Comenzamos así nuestro aprendizaje, que sobre el tema abunda en internet pero quien de inmediato llamó nuestra atención por su trabajo estructurado y paciente fue  «ObiJuan» González y su Escuela de Padawan’s «CloneWars». Por ello cuando tuvimos noticias de que se le había otorgado el premio de Google llamado O’Reilly Open Source Award en reconocimiento a su labor (aunque es tonto de nuestra parte) nos contentamos en sumo grado y de que no solamente el Software Libre esté en tan alto nivel en España sino que también el HARDWARE LIBRE está surgiendo en América tutelado por (a pocas personas llamamos por su título, y por sus títulos menos) el Ingeniero y Doctor Juan González Gómez.

 

Premio «O’Reilly 2017 Open Source Awards»

El jueves 11 de mayo en Austin (Estados Unidos), durante la celebración del congreso mundial OSCON, fue entregado el premio O’Reilly 2017. Fueron creados en el año 2005 por Tim O’Reilly y hasta el 2009 llevaban el prefijo Google-O’Reilly pero hasta la fecha de hoy simplemente lleva el nombre O’Reilly Open Source Award: un reconocimiento a los individuos por su dedicación, innovación, liderazgo y destacada contribución al código abierto.

El premio, creado y organizado por Google en colaboración con la factoría de Tim O’Reilly, desde el 2005, se entregó este jueves 11 de mayo en Austin (Estados Unidos) durante la celebración del congreso mundial OSCON, evento que reúne a toda la comunidad de ingenieros y desarrolladores de software y hardware libre.

Es así que ObiJuán se ha ganado su hito en la muy famosa Wikipedia (hasta que Skynet? cobre conciencia de sí misma y borre nuestra adición de los ganadores del año 2017 en esa página, ja, ja, ja).

«ObiJuán» González Gómez.

Eterno empedernido de la saga de películas «La Guerra de las Galaxias «Star Wars»» -¡ejem! nosotros también ?- se autodenomina por este juego de pronunciación en inglés y castellano del Maestro Jedi de los films Obi-Wan Kenobi como ObiJuán (nosotros castellanizamos aún más las cosas con la inclusión del acento) este madrileño ejemplar comenzó sus andanzas …

¡Este blog no va de ciencias sociales! No somos biógrafos de profesión, nuestra intención es dar justo reconocimiento al que «sabemos que sabe»; los lectores de este humilde portal y de nuestra cuenta Twitter pueden dar fe de que siempre reconocemos al que sabe más que nosotros y es así que aprendemos y luego difundimos el conocimiento adquirido. Sigamos pues, con nuestra entrada de hoy.

…comenzó sus andanzas en el servicio militar obligatorio («la mili») y es allí donde le «encasquetaron» el apodo por ser tan fanático de «Star Wars».

Ya desde el año 1996 «lidia» con Linux pero ya desde muy joven «lo que se le da» es lo de la informática. Sufrió lo mismo que Richard Stallman (y nosotros también desde los años 80): un mundo privativo donde te ofrecen «comprar, usar y desechar» * pero no preguntes cómo funciona*.

Uno de sus primeros cacharros fue ZX-Spectrum donde comenzó con el lenguaje BASIC (¿y quién no ha comenzado con ese lenguaje? ¡Ah, ahora los chavales estudian Python, menuda «paliza» para nosotros los vejetes!). Luego aprendió por su propia cuenta Pascal (¡ea, que yo tuve que pisar la universidad para poder aprender este lenguaje! ?) , C, Prolog, y ensamblador (eax, ebx, ebp y esp fueron sus grandes amigos). Luego al entrar en el mundo GNU/Linux reafirma C, y aprende C++ y Python.

Comenzó la universidad en 1991 y su primera obra fue el Sistema Tower Pro Tarjeta CT6811 para su sueño hecho realidad: el robot Tritt (que ya vendrá algún día el «Mazinger ?», porque ya el R2D2 lo tuvo… ¡como impresora 3D, con dinastía y todo!). De 1996 al 98 se dedica en cuerpo y alma -pesetas de por medio- al campo de los micro-robots y es cuando emprende su cruzada de hacer una España con un fuerte desarrollo endógeno para librarse de la dependencia tecnológica extranjera: producir y crear todo en su tierra natal (dichas batallas aún se libran fuertemente y se ganan poco a poco con muchísimo esfuerzo, solo que ahora no está solo, sus padawan‘s lo acompañan y apoyan).

En 2003 ya hablaba de los problemas del hardware libre mediante conferencia dictada en el VI Congreso de Hispalinux y llegó a la conclusión que son los planos de hardware son los que cumplen con las 4 premisas del software libre y por ende es así que debe ser considerado el hardware libre (ahora va de que preguntéis de dónde proviene el nombre GNU y obtendréis una respuesta enrevesada parecida).

En 2007-08 trabajó sobre un mando para wii y pudo lograr que controlara su robot Skybot, demostrando con ello que las empresas privativas tienen aún mucho más campo que cubrir si tan solo se dignaran a compartir el conocimiento.

Su «grito de guerra» es:

«Más vale proyecto publicado con licencia libre, que ciento en el cajón»

Y su lema es:

Patrimonio Tecnológico de la Humanidad: es que vamos a avanzar muchísimo más como Humanidad si compartimos el conocimiento! ¡Salimos ganando todos! La riqueza se va a distribuir muchísimo más… Esto se vio desde el principio en el mundo de la ciencia. Si tú no compartes lo que has descubierto, y te lo revisan otras personas, no avanzas, ya no es ciencia lo que haces.

Patrimonio Tecnológico de la Humanidad
Patrimonio Tecnológico de la Humanidad

Tuvo una fuerte influencia el trabajo del profesor Adrian Bowyer quien lanza al mundo la primera impresora para tercera dimensión «3D» a modo de hardware libre: fue desde entonces una revolución imparable en la cual ObiJuán se especializó y contribuyó -y seguirá aportando- en su conocimiento y masificación. Hasta ahora tiene construidas 270 impresoras 3D y podéis leer su trabajo en CloneWars en este enlace.

Así mismo lleva un canal en Youtube con multitud de tutoriales donde explica y comparte con suma paciencia su conocimiento y experiencia, añadiéndole como siempre su toque personal:

ObiJuán es apasionado de la tecnología y en 2016 comezó su proyecto épico: la reconstrucción del CPU del «Apolo 11», el proyecto espacial de la NASA que llevó a nuestra humanidad a la Luna; la «paleoarquitectura» de los ordenadores, sin duda una tarea ardua. Escuchemos en palabras del propio ObiJuán el proyecto de marras:

Para él fue una bendición la tecnología que aportó Arduino en los años 90, fue como la revista «Mecánica Popular» aplicado al mundo de la electrónica. Si Arduino abrió la posibilidad de combinar los componentes y ponerlos a funcionar con los FPGAs (Field Programmable Gate Array) tendremos la posibilidad de construir nuestros propios «chips» y eso ahora mismo es lo que mantiene más ocupado a ObiJuán. Esto es así porque a pesar de todos los títulos universitarios que ha logrado, lo que le apasiona es construir y verificar por sus propios medios (vamos que la ciencia se han de replicar los mismo resultados en las mismas condiciones): es de los que crea y observa, basado en la teoría, pero la destreza manual es bien sabido que abre nuestros cerebros a nuevas conexiones sinápticas y nuevas formas y maneras de ver las cosas, ¡es de los que dicen «no me fío de lo que me dices o alegas, dejadme probar y comprobar»!

A ObiJuán no le gustan los agradecimientos; nosotros por estos lares tampoco (de hecho, debido a la dura situación de nuestro país hasta ahora es que aceptamos donaciones) pero cuando la obra es grande ES IMPOSIBLE QUE PASE DESAPERCIBIDA. Desde 1989 que comenzamos a estudiar en la Facultad de Ingeniería de la Universidad de Carabobo nuestro punto de difusión de conocimiento era el boulevard al lado del cafetín principal, AHORA LO ES EL INTERNET POR EL MUNDO ENTERO y aunque en esa época ya sabíamos que difundir el conocimiento era la clave, no es sino hasta hace poco -en serio y en firme desde el año 2014- que entramos en el mundo del saber del software libre. Pero he aquí que ObiJuán no solo usa y difunde el software libre, ¡EL HARDWARE LIBRE TAMBIÉN!  Nos aventaja por largo rato, y además se involucra en persona en causas sociales ¿Cómo no reconocer su labor? ¡Sería una injusticia!

Títulos.

Nuestro reconocimiento y agradecimiento a su labor constante y tenaz.

 

Fuentes consultadas:

En castellano:

Por medio de Twitter:


En idioma inglés:

Download PDF