Hola de nuevo, ya estoy trasteando con un nuevo editor de código fuente que hace poco ya alcanzó la versión de producción 1 y está en el momento en que escribo en la versión 1.0.7. Estoy hablando del Atom Editor, un editor de códigos fuentes ligero, rápido, con todo tipo de plugins.. como dicen en su web: un editor hackeable del siglo 21. Es sencillo a más no poder, pero a la vez se puede mejorar instalando paquetes y pieles, que lo convierten en una potente herramienta.
Como punto de entrada me sorprendió no recuerdo donde que leí que estaba hecho en HTML, CSS y Javascript. Ya sólo esto me sorprendió así que hace un par de meses decidí instalarlo y probarlo. No probé demasiado bien, pero ahora que ya ha alcanzado cierta madurez lo he probado bien durante una semana y estos son los resultados.
Características
Al estilo Sublime Text o tipo Eclipse con un estilo ‘dark’ resulta agradable ya la primera impresión. Tus ojos descansan con colores suaves mientras lees los códigos. Como es un proyectos de Github, trae integrada la detección de cambios Git del repositorio que estés viendo. Rápido como él sólo, arranca bien, abre las ventanas rápido con un ‘click’ cada archivo. Explorador de archivos integrado. Opción de abrir un directorio, un sólo archivo, varios proyectos en la misma ventana, o varias ventanas con distintos archivos o proyectos. Puedes abrir todo tipo de archivos de texto. También imágenes, que en mi caso el poder ver las imágenes en el propio editor se agradece. Se pueden dividir las ventanas en paneles para poner en cada uno un archivo según necesitemos.
Cuando empecemos a instalar paquetes para nuestras necesidades es cuando nos daremos cuenta de lo potente que es. La comunidad está desarrollando gran cantidad de ellos para todo o casi todo lo que he buscado. En mi caso, el hacer webs usando un editor de código que en sí mismo está hecho como una web me impresiona. Le he puesto el autocompletado para los lenguajes que uso, el resaltador de error de sintáxis, el famoso minimapa y otros plugins.
Lo tenemos disponible para Linux, Mac, FreeBSD y Windows.
Cuando digo packages, aquí es lo mismo que los plugins de WordPress, los complementos de Firefox, o las aplicaciones de un sistema operativo. Pues aquí se llaman packages, que son lo que completan con infinidad de funcionalidades este fenómeno editor. En mi caso, estoy probando y me quedo con los siguientes:
atom-autocomplete-php: para autocompletar rápidamente en proyectos basados en Composer.
atom-beautify: pone bonito el código identándolo, poniendo espacios o quitándolos donde debe, etc. Si tienes instalado php-cs-fixer te formatea el código según el estándar PSR.
autocomplete-plus: es básico para que otros paquetes de autocompletado funcionen.
php-twig: compatibilidad con Twig, muestra mensajes emergentes con sugerencias también.
php-getters-setters: como su nombre indica, genera los getters y setters de una clase PHP.
minimap: este me gusta mucho porque te visualiza una ventana lateral con todo el código fuente en miniatura con el que te puedes mover por un archivo.
linter y linter-php: analiza el código mostrando menús emergentes, errores sintácticos, etc. Muy bueno, imprescindible.
docblockr: genera comentarios automáticamente según escribes en las cabeceras de clases o funciones.
custom-title: con el que puedes configurar los títulos de la ventana mostrando, por ejemplo, el nombre del proyecto, la rama y la ruta completa al archivo. Muy configurable y útil para saber donde estás.
git-plus: para hacer tareas de Git dentro del editor. En mi caso, en Linux, pulsando Ctrl+Shift+H se me despliegan los comandos disponibles.
Veo brutalmente buenos estos packages, ya cada uno que busque los suyos. Tenemos disponibles 2602 en la fecha en que escribo esto según pone en:
https://atom.io/packages
¡Hay que probarlo que es una joya de la informática! Un saludo.
Por la ley llamada LGPD, y ahora también hecho reglamento RGPD, los desarrolladores nos vemos obligados a mostrar un mensaje de si el usuario acepta que usemos cookies. Todo esto se debe en parte por el miedo por las cookies, quizá por el desconocimiento de lo que son o para qué sirven.
Las cookies son simples ficheros de texto en plano que no contienen absolutamente ningún programa. No se ejecutan ni pueden infiltrarse en un ordenador, pero ya puestos a hacer leyes no nos queda otra que obedecer.
Estoy escribiendo poco últimamente sobre programación. No me he olvidado del blog, es que gracias a Dios estoy teniendo menos tiempo. No está la cosa para echar cohetes acá en Spain pero voy a intentar apretar y no abandonar en las buenas costumbres, como por ejemplo, escribir en un blog 😉
Para instalar Bower tuve que navegar para encontrar dispersa alguna información, así que aquí les dejo todo junto en un post.
Qué es
Bower es una excelente herramienta para automatizar la gestión de tus librerías. Está creada para gestionar los fuentes de la parte front-end. Es decir, Bower nos descarga y actualiza las librerías de entorno cliente: CSS, HTML y Javascript que necesitemos. Puede ser por ejemplo las librerías de Bootstrap o jQuery.
Llegados a éste punto si ejecutamos ‘bower update’ nos saldrá un error porque no encuentra ‘node’. Ésto pasa porque el ejecutable en Ubuntu no es node es nodejs y no lo encuentra. Así que creamos un enlace simbólico y asunto solucionado.
$ sudo ln -s /usr/bin/nodejs /usr/bin/node
Ejecutar
Ya teniendolo instalado nos falta una configuración sencilla en dos ficheros. Primero un bower.json donde elegimos qué librerías necesitamos:
Si ponemos en la versión de cada dependencia latest siempre nos descargará o actualizará a la última versión de la librería. Segundo para configurar en qué directorio queremos todo podemos crear un fichero .bowerrc
Ahora todas las librerías las tendremos bajo el directorio /lib cuando ejecutemos lo siguiente:
$ bower update
Para terminar de incluir todas éstas librerías en un fichero HTML y usarlas podemos poner un HEAD parecido al siguiente: <head>
<title>Título de la web</title>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<link rel=”stylesheet” href=”lib/bootstrap/dist/css/bootstrap.min.css” type=”text/css”>
<link rel=”stylesheet” href=”lib/font-awesome/css/font-awesome.min.css” type=”text/css”>
<script src=”lib/jquery/dist/jquery.min.js”></script>
<script src=”lib/jquery-ui/jquery-ui.min.js”></script>
<script src=”lib/bootstrap/dist/js/bootstrap.min.js”></script>
<script src=”main.js”></script>
<link rel=”stylesheet” href=”estilo.css” type=”text/css”>
</head>
Ya podemos empezar a maquetar y programar usando jQuery, jQuery-UI, Bootstrap y las Fuentes Asombrosas. No hemos tenido que ir web a web descargando todas las librerías una a una. Además si ahora ejecutas en cualquier momento ‘bower update’ se te actualizarán las librerías a la última versión.
Si has llegado hasta aquí espero que te estén sirviendo de ayuda.
Cada vez menos ordenadores de sobremesa visitan las páginas web. Se venden ingentes cantidades de dispositivos que no son los clásicos ordenadores como tablets, smartphones, smart TV.. Los visitantes de una web necesitan que la página sea compatible con todo tipo de dispositivos. Bootstrap de Twitter está muy de moda, a fecha de hoy van por la versión 3.1.1 así que aprovechando para ponerme al día les dejo éste post. Al grano..
Bootstrap de Twitter es un framework de desarrollo para hacer aplicaciones web compatibles con todo tipo de dispositivos. El modelo de desarrollo cambia totalmente al modo habitual porque se da preferencia a los dispositivos móviles siendo su adaptación primera, antes que para escritorios de ordenador. Para verlo claro más abajo veremos cómo el mismo menú en caso de tener una pantalla ancha se verá en horizontal como en la imagen de arriba. Si tenemos una pantalla estrecha se visualizará desplegándose hacia abajo para que quepa todo.
Lo mismo sucede con el resto de las páginas diseñadas con Bootstrap, se adaptan según cambia el tamaño del navegador. Así tendremos una web que se puede ver correctamente en cualquier dispositivo.
Esbozando la web
Para que sea lo máximo posible compatible necesitamos utilizar el estándar HTML5 con lo que la primera estructura quedará así:
Es importante saber que con la metaetiqueta “viewport” definimos la escala inicial de la página. Ésto se utiliza para agrandar o disminuir con la función de zoom de los navegadores.
Añadiendo los archivos externos
Prefiero descagar los archivos de las páginas oficiales (getbootstrap.com) y usarlos dentro del proyecto en cuestión. Pero para simplificar ésta primera plantilla he puesto los CDN. Será necesario tener conexión a Internet para ejecutar la web y se vean el aspecto estilo Bootstrap. Si los incluyes dichos archivos no será necesario Internet. Añadimos dentro del <head> lo siguiente:
Ésto simplemente enlaza a los archivos públicos que tenemos en Internet. Te ahorras espacio usando los CDN, pero dependes de que dichos archivos estén disponibles para que tu web funcione correctamente.
Algunos componentes para probar
A continuación he puesto un menú de navegación y tres paneles, uno simple, otro con título y un tercero con título con estilo de cabecera. Añadiendo en el body lo siguiente tendremos la barra de navegación que viene en la documentación oficial:
<nav class="navbar navbar-default" role="navigation"> <!-- El logotipo y el icono que despliega el menú se agrupan para mostrarlos mejor en los dispositivos móviles --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse"> <span class="sr-only">Desplegar navegación</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Logotipo</a> </div>
<!-- Agrupar los enlaces de navegación, los formularios y cualquier otro elemento que se pueda ocultar al minimizar la barra --> <div class="collapse navbar-collapse navbar-ex1-collapse"> <ul class="nav navbar-nav"> <li class="active"> <a href="#">Enlace #1</a> </li> <li> <a href="#">Enlace #2</a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Menú #1 <b class="caret"></b> </a> <ul class="dropdown-menu"> <li> <a href="#">Acción #1</a> </li> <li> <a href="#">Acción #2</a> </li> <li> <a href="#">Acción #3</a> </li> <li class="divider"> </li> <li> <a href="#">Acción #4</a> </li> <li class="divider"> </li> <li> <a href="#">Acción #5</a> </li> </ul> </li> </ul>
Nota que los paneles están dentro de un <div class=”container”>. Éste div contenedor se suele usar para el contenido de la web, alinea lo que tengas dentro, para algunos componentes es necesario si no puede que no se vean bien.
Ahora es el momento de probar con un móvil el fichero, o con una tablet. Si quieres verlo claro directamente en el ordenador puedes estrechar horizontalmente el navegador con la página cargada y verás cómo se modifica el aspecto.
Usando archivos incluidos en el proyecto
Si descargamos y descomprimimos los archivos de la página oficial getbootrap.com, tendremos tres directorios con todos los archivos necesarios menos jQuery. jQuery lo podemos descargar de su página oficial http://code.jquery.com/jquery-2.1.0.min.js y copiarlo al directorio js. Ahora tendremos un directorio /css otro /fonts y un tercero /js con todo incluido. En éste caso viendo los archivos que tengamos según la versión podremos incluir en la cabecera el código siguiente:
<nav class="navbar navbar-default" role="navigation"> <!-- El logotipo y el icono que despliega el menú se agrupan para mostrarlos mejor en los dispositivos móviles --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse"> <span class="sr-only">Desplegar navegación</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Logotipo</a> </div>
<!-- Agrupar los enlaces de navegación, los formularios y cualquier otro elemento que se pueda ocultar al minimizar la barra --> <div class="collapse navbar-collapse navbar-ex1-collapse"> <ul class="nav navbar-nav"> <li class="active"> <a href="#">Enlace #1</a> </li> <li> <a href="#">Enlace #2</a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Menú #1 <b class="caret"></b> </a> <ul class="dropdown-menu"> <li> <a href="#">Acción #1</a> </li> <li> <a href="#">Acción #2</a> </li> <li> <a href="#">Acción #3</a> </li> <li class="divider"> </li> <li> <a href="#">Acción #4</a> </li> <li class="divider"> </li> <li> <a href="#">Acción #5</a> </li> </ul> </li> </ul>
Si todo ha ido bien debemos de ver la página como la de la imagen de al lado cuando hacemos la ventana del navegador estrecha. Espero haber resumido correctamente la documentación oficial como para poder empezar a jugar con el framework Bootstrap.
Sólo me queda decir que los ejemplos de componentes que he puesto los he sacado de la documentación oficial, en ella estan todos los que hay disponibles. Como por ejemplo el uso de rejillas, las fuentes para los pequeños gráficos incluidos, y un largo etcétera..
Hace tiempo que no escribo, parece que estoy olvidándome de la programación pero no es así. He estado bastante liado, tal vez demasiados proyectos o demasiado “querer hacer”. El que mucho abarca poco aprieta, o el que mucho aprieta poco abarca :S así que espero seguir escribiendo, aunque sea los fines de semana.
En éstos días he estado viendo cómo se puede medir la calidad de una página web. Desde un punto de vista se puede medir la cantidad y calidad de los algoritmos que trabajan en la parte servidor, sus funciones o servicios que dan. Por otro lado tenemos las validaciones de la parte cliente, si cumple con los estándares de los lenguajes..
Unos chequeos que podemos hacer para validar la parte cliente:
http://validator.w3.org/ para validar el lenguaje de marcado según la especifiación internacional.
Con ésto ya hay para hacerle algunos checkeos automáticos. Son pocas las webs que cumplen con todos los estándares, pero la organización mundial donde se organiza todo ésto está ahí haciendo su trabajo, queda de nuestra mano todo lo demás sino te arriesgarás a que la web pueda no funcionar bien en algunos navegadores. Ten en cuenta también que cumpliendo con la accesibilidad le hecharás una mano a personas que tienen problemas visuales, a los que necesitan traductores automáticos, de otras culturas, y un largo etcétera. La accesibilidad es algo muy importante y se nos pueden pasar por alto.
Por otro lado tenemos también los criterios de diseño como por ejemplo: “Si algo es un botón que parezca un botón.” no le pongamos una imagen con luces intermitentes.. ésto ya es otro tema, a ver si pronto tengo tiempo.. Si estás leyendo ésto gracias por haber llegado hasta aquí 🙂
El tiempo pasa y no vuelve, el valor más preciado que tenemos, cuando a uno le falta es cuando lo tiene en cuenta. Estoy sacando tiempo de debajo de las piedras para seguir escribiéndoles. Vienen días de tormenta, hace mucho viento, parece que llueve pero no llueve, la prima de riesgo sube y baja, los políticos siguen con sus historias, y yo sigo con lo mío, así que aquí hoy os dejo algo más sobre Swing. En concreto sobre componentes para dar formato a textos y algo más.
En éste minitutorial, voy a dar un repaso a los componentes que sólo admiten cierto tipo de valores como los JFormattedTextField. Otro componente interesante, el JEditorPane, que admite por defecto tres tipos de contenido: el texto plano normal y corriente de siempre (text/plain), texto enriquecido (text/rtf), o un documento en HTML (text/html). Y otra caja de texto, el JTextPane, que admite incluso otros componentes Swing como etiquetas, botones, etcétera…
Para éste post he utilizado la versión JDK 7 update 9, y Eclipse Juno EE con el plugin Swing Designer.
JFormattedTextField
Éste componente hereda del JTextField, con lo que tiene los mismos métodos y se usa de manera parecida. La diferencia que tiene con respecto a los demás componentes de texto es que permite establecer una máscara de entrada para los datos que el usuario escribe. Por ejemplo si queremos poner un código postal, un número de teléfono, etcétera..
Éste componente es uno de los más prácticos porque bien programado nos aseguramos de que el usuario va a poner lo que queremos que ponga. La carencia que tiene es que no admite expresiones regulares directamente, pero se puede sortear éste problema.
Al constructor de JFormattedTextField, se le pasa un objeto nuevo de tipo MaskFormatter, y éste se encarga de usar la máscara de entrada para admitir o no los valores de entrada.
Podemos usar en la máscara los siguientes caracteres para contruir nuestra máscara:
# cualquier número. ‘ carácter especial. U carácter, que lo modifica a mayúsculas. L carácter, que lo modifica a minúsculas. A carácter o número. ? cualquier carácter. * cualquier cosa. H cualquier caracter hexadecimal, es decir, del 0 al 9 y de la ‘a’ a la ‘f’ o de la ‘A’ a la ‘F’.
También podemos comprobar con una expresión regular si el valor introducido es correcto. Tenemos un ejemplo programado, creando un objeto nuevo de tipo RegexFormatter aquí:
Si quieres construir el tuyo propio lo que debes hacer es siguiendo el siguiente código reprogramar el método stringToValue, comprobando que el texto de entrada es válido:
JFormattedTextField formattedTextField = new JFormattedTextField(new AbstractFormatter() { @Override public String valueToString(Object value) throws ParseException { // TODO Auto-generated method stub return null; }
Si quieres generar con Eclipse el código esqueleto, cuando llegues a donde pone new Abstract… le das a Ctrl + Espacio y te saldrán las opciones que tienes, ésto lo puedes hacer mientras que escribes en cualquier parte del programa para ir más rápido, entonces eliges dándole a Enter y te genera el código de aquí arriba. Ya con ésto puedes usar una expresión regular usando un ‘matcher’. Pero ésto ya sería para otro post.
Éste componente admite tres tipos de textos formateados por defecto: texto plano, documento enriquecido RTF y HTML. Un ejemplo de uso es el siguiente:
JEditorPane editorPane = new JEditorPane(); editorPane.setContentType("text/html"); editorPane.setText("<h1>Título</h1>" + "<p>Ésto <b>es</b> un <i>párrafo</i>.</p>"); editorPane.setBounds(10, 92, 481, 134); contentPane.add(editorPane);
Con la función setContentType se establece el tipo de texto, que permite: text/plain para texto normal y corriente, con text/rtf podemos poner texto enriquecido siguiendo su especificación, y el text/html para páginas web.
Éste es un subcomponente de JEditorPane, podemos usarlo exactamente igual pero además añade que podemos insertar dentro otros componentes con la función insertComponent(nombreComponente).
JTextPane textPane = new JTextPane(); textPane.setContentType("text/html"); textPane.setText("<h1>Título</h1>" + "<p>Ésto <b>es</b> un <i>párrafo</i>.</p>"); JButton boton = new JButton("Ésto es un botón"); textPane.insertComponent(boton); textPane.setBounds(10, 262, 481, 125); contentPane.add(textPane);
Se pueden añadir todo tipo de componentes, o por lo menos la declaración de insertComponent recibe un parámetro de tipo Component, con lo que habría que probar a ver si los admite todos.
Terminando
Es interesante la función setPage(URL) que admite tanto el JTextPane como el JEditorPane, con la que podemos poner una página de Internet o de la red local dentro del componente. En el ejemplo adjunto abajo se utiliza la función setPage para cargar contenido HTML. Haciendo un navegador casero.
Es interesante que también admite editar el contenido el JTextPane y el JEditorPane, con lo que hay posibilidades para hacer un editor de páginas web, por ejemplo, o de texto enriquecido. Se le pueden añadir unos botones alrededor de la ventana para cambiar los formatos.. etcétera.. ya cada uno que imagine y que haga, hay mucho juego.
Bueno con ésto ya hay para hecharle un buen vistazo a éstos componentes, espero que sirva. A continuación les dejo todo el código de ejemplo. También adjunto un fichero comprimido con todo, hay un .jar ejecutable dentro para verlo en marcha. Para ejecutarlo sólo necesitas el JRE instalado. Aquí va el código:
// éste es el panel principal que todo lo contiene private JPanel contentPane;
// función que primero se ejecuta creando el JFrame public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { Principal frame = new Principal(); // visualiza el frame frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); }
// constructor de la clase, // se usa para crear todos los componentes y programar // todo el funcionamiento public Principal() throws ParseException {
// se configura la ventana... setTitle("Java Swing 7 Textos y otros by Jnj"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 517, 438); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null);
// la primera etiqueta JLabel lblJformattedtext = new JLabel("JFormattedTextField"); lblJformattedtext.setBounds(10, 11, 133, 14); contentPane.add(lblJformattedtext);
// la etiqueta del JEditorPane JLabel lblJeditorpane = new JLabel( "JEditorPane que accede a http://localhost/"); lblJeditorpane.setBounds(10, 67, 250, 14); contentPane.add(lblJeditorpane);
// la etiqueta del JTextPane JLabel lblJtextpane = new JLabel("JTextPane"); lblJtextpane.setBounds(10, 237, 109, 14); contentPane.add(lblJtextpane);
// la caja de texto formateado // con una máscara de formato JFormattedTextField formattedTextField = new JFormattedTextField( new MaskFormatter("(####)#########")); formattedTextField.setBounds(10, 36, 481, 20); contentPane.add(formattedTextField);
// el JEditorPane que usa una página web // accediendo al servidor web de nuestra // máquina local JEditorPane editorPane = new JEditorPane(); // es obligatorio usar el try catch para capturar errores try { // establece la página editorPane.setPage("http://localhost/"); } catch (IOException e) { e.printStackTrace(); } editorPane.setBounds(10, 92, 481, 134); contentPane.add(editorPane);
// y el JTextPane JTextPane textPane = new JTextPane(); // se establece el tipo textPane.setContentType("text/html"); // con un texto en HTML textPane.setText("<h1>Título</h1>" + "<p>Ésto <b>es</b> un <i>párrafo</i>.</p>"); // se crea un botón JButton boton = new JButton("Ésto es un botón"); // se inserta el botón dentro de la caja de texto textPane.insertComponent(boton); textPane.setBounds(10, 262, 481, 125); contentPane.add(textPane); } }
Me hago eco de una noticia que últimamente está corriendo por Internet, con una guía, a mi entender bastante complicada para poner una web o archivos en descarga directa en Google Drive. La fuente de la noticia que leo es:
… buscando un poco más, encontré la guía de Developers de Google:
https://developers.google.com/drive/publish-site
He hecho un par de pruebas, aparte de que está en inglés, se habla del webViewLink y de programar para crear un directorio público :S todo ésto se me va complicando… Una web de ejemplo que nos han dejado los de Google es:
Voy a ir al grano, reduciendo todo el proceso anterior, lo que necesitas es conseguir la cadena que identifica tu directorio que vas a usar para poner tus archivos. En el ejemplo anterior de la gente de Google, es 0B716ywBKT84AcHZfMWgtNk5aeXM, éste es su identificador para el ejemplo que se han currado. Nosotros entonces podemos reducir el proceso, y para ello sólo hay que seguir 3 pasos:
Crear una carpeta dentro de tu Google Drive.
La compartes como público en la web. Con lo que te van a dar un enlace como el siguiente https://docs.google.com/folder/d/cadenaQueIndicaTuDirectorio/edit (lo puedes ver en la ventana que sale para configurar como compartes el directorio).
Ya sólo tienes que poner tu cadenaQueIndicaTuDirectorio en la dirección URL para que se pueda acceder desde un navegador.
Podrás acceder y enviar tu dirección a quien quieras, y los archivos podrán verse de la forma: https://googledrive.com/host/cadenaQueIndicaTuDirectorio/index.html https://googledrive.com/host/cadenaQueIndicaTuDirectorio/miArchivo.zip https://googledrive.com/host/cadenaQueIndicaTuDirectorio/loQueSeaQueQuieraPublicar.extension etcétera…
Si pones en éste directorio un archivo index.html y el resto de una página web, ya tienes acceso directo como en cualquier hosting. Puedes usar las tecnologías de programación cliente, como HTML, CSS, Javascript… Lo único malo es la dirección URL tan compleja, pero también se puede redirigir un domonio ocultando éste URL. De todas maneras dependes de lo que haga Google con tu cuenta de Drive. Pero ya es bastante lo que nos estan dando, que es gratis, o por lo menos yo me beneficio de su cuenta gratuita…