Google Chrome integrará WebRTC

Antes que nada:

WebRTC es un proyecto libre y abierto que permite a los navegadores la posiblidad de integrar Comunicación en Tiempo Real (Real-Time Communications o RTC) mediante simples JavaScript Apis.

Ya hace algunos años hemos visto la popularidad que dió Flash al video y la comunicación en tiempo real, el problema es que siempre se tenía que usar los plugins para que este funcione.

Después Google sorprendió con la comunicación en video desde Gmail, pero de la misma manera se tenía que instalar un pequeño plugin.

WebRTC fue presentado a inicios de junio y con la noticia de que Chrome lo integre en sus entrañas, Google se está preparando a desafiar a Microsoft y su reciente compra de Skype. El hecho de tener nativamente código en los navegadores más usados, permitirá que la comunicación en tiempo real se extienda en diferentes sistemas operativos y dispositivos sin distinción.

Otra ventaja es que los desarrolladores web podremos crear aplicaciones que permitirán el RTC y la comunicación mundial va a dar un gran paso. Ahora todo tiene que ver con la web.

Este proyecto está soportado y está siendo incluido a la W3C por Google, Mozilla y Opera.

Diagrama de funcionamiento WebRTC

Visto en Genbeta

Mozilla Bespin: Un editor de código basado en web

Bespin es un proyecto de un editor de código basado en web, libre, extensible que permitirá incrementar la productividad de desarrollo. Fue desarrollado usando HTML 5. Por ahora está en fase de prueba en su versión 0.1, lo cual sólo permite el registro de usuarios mas no crear propios proyectos o archivos. Obviamente en Firefox se ve bien, pero no funciona con IE7. El proyecto en si es interesante y novedoso, esperamos que en la siguiente versión ya se pueda jugar mas con este editor.
Introducing Bespin from Dion Almaer on Vimeo. webkit-editor-medium Bespin 0.1 Running in Firefox 3.0 Enlace: Mozilla Labs: Bespin

PostgreSQL Day Perú 2007

Este sábado, se realizará un pequeño evento sobre PostgreSQL:

Pedimos disculpa si el presente mail le llega por diversas listas.

La comunidad PostgreSQL Peru (http://www.postgresql.org.pe) tiene el agrado de invitarte a participar de nuestro primer PostgreSQL Day a llevarse a cabo este sábado 8 de Septiembre de 3pm a 8pm en los locales de la Universidad Cayetano Heredia de Miraflores (Av. Armendariz 445 - Miraflores - Lima).

El programa del evento es:

  • 3:00 pm Inauguración
    • Palabras de bienvenida al evento (10")
  • 3:10 pm Introducción a PostgreSQL
    1. Que es PostgreSQL (20")
    2. Estandares SQL92 AnSI y SQL99 (20")
    3. Comparativas contra otros dbms libres (20")
  • 4:10 pm Instalación de PostgreSQL en diversas plataformas
    1. Debian (15")
    2. CentOS (15")
    3. Windows (15")
    4. FreeBSD (15")
    5. Preguntas (20")
  • 5:30pm Break 15"
  • 5:45pm Entornos de Administración
    1. PgAdmin3 (20")
    2. PhpPgAdmin (20")
    3. Consola (20")
    4. Preguntas (20")
  • 7:05pm Mesa redonda de experiencias
    1. Experiencia Xendra (10")
    2. Experiencia Cargo Master (10")
    3. Experiencias EQSoft-Asoc. Empleados del BCP (10")
    4. Rueda de preguntas (25")

No es necesario inscribirse, se ingresará por orden de llegada, tenemos capacidad para recibir a 150 personas por lo cual te invitamos a llegar temprano, mas información sobre el evento será publicada en nuestra página web en los siguientes días, las diapositivas del evento serán publicadas en el mismo lugar.

Información sobre PostgreSQL: PostgreSQL es un motor de base de datos totalmente libre, multiplataforma y de altas prestaciones, probado en varios proyectos a nivel nacional e internacional, es estable, rápido y fácil de utilizar, si quieres saber mas de PostgreSQL puedes visitar nuestra página web en http://www.postgresql.org.pe o la página principal del proyecto en http://www.postgresql.org

Si estás cerca y todavía sigues usando ciegamente MySQL te gustaría conocer algo más sobre PostgreSQL, ésta es tu oportunidad. 😉

Unir documentos PDF con .NET

Actualización (19/07/2007): Luis Ruiz Pavón comenta una forma más sencilla de unir documentos usando iTextDotNet.

Una pequeña clase que hace uso de iText# (Software Libre) para unir dos o más documentos PDF en uno solo.

csharp:
using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

public class PdfMerge
{
    private BaseFont baseFont;
    private bool enablePagination = false;
    private readonly List<PdfReader> documents;
    private int totalPages;

    public BaseFont BaseFont
    {
        get { return baseFont; }
        set { baseFont = value; }
    }

    public bool EnablePagination
    {
        get { return enablePagination; }
        set
        {
            enablePagination = value;
            if (value && baseFont == null)
                baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
        }
    }

    public List<PdfReader> Documents
    {
        get { return documents; }
    }

    public void AddDocument(string filename)
    {
        documents.Add(new PdfReader(filename));
    }
    public void AddDocument(Stream pdfStream)
    {
        documents.Add(new PdfReader(pdfStream));
    }
    public void AddDocument(byte[] pdfContents)
    {
        documents.Add(new PdfReader(pdfContents));
    }
    public void AddDocument(PdfReader pdfDocument)
    {
        documents.Add(pdfDocument);
    }

    public void Merge(string outputFilename)
    {
        Merge(new FileStream(outputFilename, FileMode.Create));
    }
    public void Merge(Stream outputStream)
    {
        if (outputStream == null || !outputStream.CanWrite)
            throw new Exception("OutputStream es nulo o no se puede escribir en éste.");

        Document newDocument = null;
        try
        {
            newDocument = new Document();
            PdfWriter pdfWriter = PdfWriter.GetInstance(newDocument, outputStream);

            newDocument.Open();
            PdfContentByte pdfContentByte = pdfWriter.DirectContent;

            if (EnablePagination)
                documents.ForEach(delegate(PdfReader doc)
                                  {
                                      totalPages += doc.NumberOfPages;
                                  });

            int currentPage = 1;
            foreach (PdfReader pdfReader in documents)
            {
                for (int page = 1; page <= pdfReader.NumberOfPages; page++)
                {
                    newDocument.NewPage();
                    PdfImportedPage importedPage = pdfWriter.GetImportedPage(pdfReader, page);
                    pdfContentByte.AddTemplate(importedPage, 0, 0);

                    if (EnablePagination)
                    {
                        pdfContentByte.BeginText();
                        pdfContentByte.SetFontAndSize(baseFont, 9);
                        pdfContentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER,
                            string.Format("{0} de {1}", currentPage++, totalPages), 520, 5, 0);
                        pdfContentByte.EndText();
                    }
                }
            }
        }
        finally
        {
            outputStream.Flush();
            if (newDocument != null)
                newDocument.Close();
            outputStream.Close();
        }
    }

    public PdfMerge()
    {
        documents = new List<PdfReader>();
    }
}

Si bien es cierto que hay muchas cosas por mejorar, creo que para escenarios no muy complejos basta y sobra.

Pueden descargar la solución creada en Visual Studio 2005 que -- incluye el ensamblado iText# y -- como ejemplo une dos papers bastante interesantes ("Composable Memory Transactions" y "Static Typing Where Posible, Dynamic Typing When Needed: The End of The Cold War Between Programming Languages").

Nota: La clase está basada en el artículo Merge PDF files with iText.

Cecil: Examina y modifica ensamblados .NET al vuelo

Cecil es una librería creada por Jean-Baptiste Evain que permite examinar y modificar los ensamblados .NET de manera sencilla, a su vez estos cambios pueden sobreescribir el original o ser almacenados en un ensamblado nuevo.

Veamos dos ejemplos sencillos que muestran como funciona Cecil:

  1. Convertir una aplicación de consola a una aplicación Windows.- Si compilamos el siguiente código como una aplicación de consola, al ejecutarse mostrará 2 ventanas (una para la consola y otra para el formulario creado):

    csharp:
    // console.cs
    using System;
    using System.Windows.Forms;

    class Program
    {
        static void Main(string[] args)
        {
            Form frm = new Form();
            frm.Height = 100;
            frm.Width = 100;
            frm.ShowDialog();
        }
    }

    Para hacer la conversión usando Cecil, lo único que se tiene que hacer es:

    csharp:
    using Mono.Cecil;
    using Mono.Cecil.Cil;

    class Program
    {
        static void Main(string[] args)
        {
            AssemblyDefinition assembly = AssemblyFactory.GetAssembly("consola.exe");
            assembly.Kind = AssemblyKind.Windows;
            AssemblyFactory.SaveAssembly(assembly, "windows.exe");
        }
    }

    Si ejecutamos windows.exe, esta vez sólo se mostrará el formulario creado.

  2. Cambiar el espacio de nombres y modificadores de acceso: En este ejemplo se va a cambiar el espacio de nombres de las clases y los modificadores de acceso de un ensamblado denominado ClassLibrary1.dll

    csharp:
    namespace ClassLibrary1.Utility
    {
        public enum HashMethod
        {
            MD5,
            SHA1
        }

        internal class Security
        {
            public static string MD5(string password)
            {
                throw new System.Exception("The method or operation is not implemented.");
            }
        }
       
        class Validation
        {
            public static bool IsEmail(string email)
            {
                throw new System.Exception("The method or operation is not implemented.");
            }
            private void IsUrl(string url)
            {
                throw new System.Exception("The method or operation is not implemented.");
            }
            private void IsIp(string ip)
            {
                throw new System.Exception("The method or operation is not implemented.");
            }
        }
    }

    Para hacer realizar los cambios en el ensamblado de arriba:

    csharp:
    using Mono.Cecil;
    using Mono.Cecil.Cil;

    namespace CecilDemo
    {
        class Program
        { 
            static void Main(string[] args)
            {
                string assemblyName = "ClassLibrary1.dll";

                /* Cargar el ensamblado */
                AssemblyDefinition assembly = AssemblyFactory.GetAssembly(assemblyName);

                /* Iterar sobre los tipos del módulo principal */
                foreach (TypeDefinition type in assembly.MainModule.Types)
                {
                    /* Cambiar el espacio de nombres y el
                     * nivel de acceso a todas las clases
                     */

                    if ("<Module>" != type.Name)
                    {
                        type.Namespace = type.Namespace.Replace("ClassLibrary1", "Buayacorp");
                        type.Attributes |= TypeAttributes.Public;                   
                    }
                   
                    /* Hacer que todos los métodos de la clase Validation
                     * sean públicos y miembros de clase (static).
                     */

                    if ("Validation" == type.Name)
                    {
                        foreach (MethodDefinition method in type.Methods)
                        {
                            /* Eliminar el atributo 'private' de cada uno de los métodos */
                            if ((method.Attributes & MethodAttributes.Private) == MethodAttributes.Private)
                            {
                                method.Attributes ^= MethodAttributes.Private;
                            }

                            method.Attributes |= MethodAttributes.Public | MethodAttributes.Static;                       
                        }
                    }
                }
                /* Almacenar el nuevo ensamblado en CustomClassLibrary1.dll */
                AssemblyFactory.SaveAssembly(assembly, "Custom" + assemblyName);
            }
        }
    }

    Si observamos el ensamblado modificado con Reflector, veremos que se realizaron los cambios.

El uso de esta herramienta obviamente va a depender de las necesidades y posibles limitaciones de acceso al código fuente que tengamos, puesto que no sería nada productivo usar Cecil para hacer cosas parecidas a los ejemplos que muestro. 😀