Enviar correo internamente usando JavaMail API


En realidad no es demasiado difícil crear un aplicación capaz de enviar correos electrónicos usando el IDE de Android Studio  .De hecho gracias al APi de Javmail   podremos enviar e-mails sin utilizar la aplicación de correo electrónico que android incluye por defecto utilizando javamail API para crear nuestro propio email del remitente herramientas que enviará correo internamente.

Tenemos que seguir los pasos que se dan a continuación:

1. Descargar los archivos de biblioteca de api de java.

Tenemos que descargar  tres   librerías java: 

    1. activation.jar
    2. mail.jar.
    3.  additionnal.jar

    Lo puede descargar de Clic aquí.

    2 Ahora crear una  app en Android studio

    3-Ir a la carpeta del proyecto -> aplicación -> libs y agregue todos los archivos jar en libs ahora uno por uno, haga clic en biblioteca de archivos en la opción haga clic en Agregar como biblioteca en todos los archivos jar.

    libs

    También puede Agregar biblioteca por otro camino, pero lo  importante es que incluya esta tres librerías:

    1. activation.jar
    2. mail.jar.
    3.  additionnal.jar

    Ir a archivo >Proyecto estructura > seleccione aplicación> opción derecha haga clic en dependencias ahora haga clic en el botón de pulse(+) para agregar > seleccione dependencia de archivo> archivo seleccione Biblioteca > OK.

    addjar

    4. Ahora abrir el archivo manifest.xml y poner los permisos de internet.

     <uses-permission android:name="android.permission.INTERNET"/>

    Ahora busque manifiesto está buscando como.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.sp.sendmailinternally">
        <uses-permission android:name="android.permission.INTERNET"/>
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>

    4. Ahora abrael fichero  activity_main.xml para crear el archivo de diseño agregar después de código.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.sp.sendmailinternally.MainActivity">
        <EditText
            android:id="@+id/edittext_recipient_id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Recipient Email"
            android:textSize="18sp" />
        <EditText
            android:id="@+id/edittext_subject"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Subject"
            android:textSize="18sp" />
        <EditText
            android:id="@+id/edittext_message"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="start"
            android:hint="Message"
            android:textSize="18sp" />
        <Button
            android:id="@+id/btn_send_mail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Send Mail"
            android:textAllCaps="false" />
    </LinearLayout>

    5. Cree la  clase de Asyntask para el envío de llamada correo API.

    package com.sp.sendmailinternally;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.os.AsyncTask;
    import android.widget.Toast;
    import java.util.Properties;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    /**
     * Created by ps205 on 3/1/17.
     */
    public class SendMailAsynTask extends AsyncTask<Void, Void, Void> {
        //Declaring Variables
        private Context context;
        private Session session;
        //Information to send email
        private String email;
        private String subject;
        private String message;
        //Progressdialog to show while sending email
        private ProgressDialog progressDialog;
        //Class Constructor
        public SendMailAsynTask(Context context, String email, String subject, String message) {
            //Initializing variables
            this.context = context;
            this.email = email;
            this.subject = subject;
            this.message = message;
        }
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //Showing progress dialog while sending email
            progressDialog = ProgressDialog.show(context, "Sending message", "Please wait...", false, false);
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            //Dismissing the progress dialog
            progressDialog.dismiss();
            //Showing a success message
            Toast.makeText(context, "Message Sent", Toast.LENGTH_LONG).show();
        }
        @Override
        protected Void doInBackground(Void... params) {
            //Creating properties
            Properties props = new Properties();
            //Configuring properties for gmail
            //If you are not using gmail you may need to change the values
            props.put("mail.smtp.host", "smtp.gmail.com");
            props.put("mail.smtp.socketFactory.port", "465");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.port", "465");
            //Creating a new session
            session = Session.getDefaultInstance(props,
                    new javax.mail.Authenticator() {
                        //Authenticating the password
                        protected PasswordAuthentication getPasswordAuthentication() {
                            return new PasswordAuthentication(Config.EMAIL, Config.PASSWORD);
                        }
                    });
            try {
                //Creating MimeMessage object
                MimeMessage mm = new MimeMessage(session);
                //Setting sender address
                mm.setFrom(new InternetAddress(Config.EMAIL));
                //Adding receiver
                mm.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
                //Adding subject
                mm.setSubject(subject);
                //Adding message
                mm.setText(message);
                //Sending email
                Transport.send(mm);
            } catch (MessagingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    6. Ahora abra MainActivity.java y agregue el siguiente código.

    package com.sp.sendmailinternally;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    public class MainActivity extends AppCompatActivity {
        EditText edittext_recipient_id, edittext_subject, edittext_message;
        Button btn_send_mail;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //initializr vista para encontar vista por id
            edittext_recipient_id = (EditText) findViewById(R.id.edittext_recipient_id);
            edittext_subject = (EditText) findViewById(R.id.edittext_subject);
            edittext_message = (EditText) findViewById(R.id.edittext_message);
            btn_send_mail = (Button) findViewById(R.id.btn_send_mail);
    //activar un listener  onclick en un  boton
            btn_send_mail.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //get  input data from view
                    String mRecipientMail = edittext_recipient_id.getText().toString();
                    String mSubject = edittext_subject.getText().toString();
                    String mMessage = edittext_message.getText().toString();
                    new SendMailAsynTask(MainActivity.this, mRecipientMail, mSubject, mMessage).execute();
    //llama al contructor de send mail asyntask mediante el envio de un parametroperameter } }); } }

    7. Ya puede construir y ejecutar la aplicación  

    Nota:- cuando ponga su id debe ser accesible acceso menos seguro aplicaciones .Para cambiar configuración para motivos de seguridad de correo vaya a cambiar la configuración   y actiíela .

     

    sendmail1

    Por cierto todo el código  esta disponible en descargar código fuente

     

     

     

    ¿Que se puede hacer para mejorar el rendimiento de las consultas en Oracle 11?


    Tradicionalmente para mejorar el rendimiento de las consultas en SQL contra una BBDD Oracle , una vez optimizada la consulta con técnicas  de Tuneling ( por ejemplo usando Hints si procede) ,   siempre pasamos a dos técnicas clásicas :

    • Reconstruyendo los  índices existente en base de datos ,para lo cual previamente comprobaremos si esos índices deberían de ser reconstruidos  
    • Actualizando estadísticas sobre las tablas que realizamos las consultas.

    Veamos mas despacio de que estamos hablando: 

     

    Reconstrucción de indices

    El índice de una base de datos es una estructura de datos que mejora la velocidad de las operaciones, permitiendo un rápido acceso a los registros de una tabla por lo que se suelen usar sobre aquellos campos sobre los cuales se vayan a realizar búsquedas frecuentes dado que su  funcionamiento es similar al índice de un libro: guardando duplas de elemento que se desea indexar junyo a su posición en la base de datos, de modo que para buscar un elemento que esté indexado, sólo necesitamos que buscar en el índice de dicho elemento para, una vez encontrado, devolver el registro que se encuentre en la posición marcada por el índice.

    Los índices pueden ser creados usando una o más columnas, preparando la base de datos tanto para búsquedas rápidas al azar como para ordenaciones eficientes de los registros.

    Los índices son construidos sobre árboles B, B+, B* o sobre una mezcla de ellos, funciones de cálculo u otros métodos.

    El espacio en disco requerido para almacenar el índice es típicamente menor que el espacio de almacenamiento de la tabla (puesto que los índices generalmente contienen solamente los campos clave de acuerdo con los que la tabla será ordenada, y excluyen el resto de los detalles de la tabla), lo que da la posibilidad de almacenar en memoria los índices de tablas que no cabrían en ella. En una base de datos relacional un índice es una copia de parte de una tabla.

    La siguiente consulta SQL mostrará el tamaño en megabytes de un índice determinado, en nuestro caso del índice PK_FACTURACION_CODIGO perteneciente a la tabla FACTURACION y el campo CODIGO del ejemplo. La consulta SQL para mostrar el tamaño ocupado por un índice es la siguiente:

    select segment_name, sum(bytes)/1024/1024 MB
    from dba_extents
    where segment_name = ‘INDICE DE EJEMPLO’
    group by segment_name

     

     

    Es importante periódicamente examinar y determinar qué índices son susceptibles de ser reconstruidos. Cuando un índice está descompensado puede ser porque algunas partes de éste han sido accedidas con mayor frecuencia que otras dando como resultado problemas de contención de disco o cuellos de botella en el sistema.

    Normalmente reconstruimos un índice con el comando ALTER INDEX  (esta sentencia se utiliza para cambiar o reconstruir un índice existente en la base de datos).

    Para poder ejecutar este comando el índice debe de estar en el propio esquema donde intentes ejecutarlo o deberías de tener el privilegio alter any index. También tenemos que tener en cuenta que para realizar la reconstrucción de un índice deberíamos de tener cuota suficiente sobre el tablespace que lo lanzamos.

    Para reconstruir un índice bastaría con lazar la siguiente sentencia

    ALTER INDEX <index_name> REBUILD;

    Para reconstruir una partición de un índice podríamos hacer lo siguiente

    ALTER INDEX <index_name> REBUILD PARTITION <nb_partition> NOLOGGING;

    Nota: En algunos casos cuando alguno de los índices tiene algún tipo de corrupción no es posible reconstruirlo. La solución en este caso es borrar el índice y recrearlo

     

     

     

    Actualización de estadísticas

    Cuando una base de datos Oracle recibe una sentencia “SQL” para resolver una consulta, se llevan a cabo diversas acciones para lograr la entrega del resultado.

    Dentro de los diversos pasos uno de los más importantes es el llevado a cabo por el optimizador basado en costos “Cost Based Optimizer o CBO”. Para que el “CBO” pueda determinar de forma exacta el plan de ejecución de para un “SQL Query” debe disponer de la información de las estadísticas de las tablas e índices que participan en el “SQL Query”, esta información comúnmente es conocida como “Optimizer statistics” “Estadisticas del optimizador”, la misma describe como esta compuesto y distribuido internamente el objeto.

    Estas estadísticas son utilizadas por el optimizador para elegir el mejor plan de ejecución para cada instrucción SQL.

    El tiempo necesario para colectar las estadísticas en algunos casos puede ser de gran medida. En el manejador se pueden utilizar diversos métodos para tratar de reducir el tiempo de esta tarea en la mayor proporción posible.

     

    Es importante tener por tanto actualizadas las estadísticas de la base de datos. Para saber si las estadísticas se están lanzando correctamente podemos hacer una consulta sobre la tabla ALL_INDEXES en oracle 11  (en Oracle 10  es  dba_indexes )y ver el campo last_analyzed para observar cuando se ejecutaron sobre ese índice las estadísticas.

    Nota: la columna “LAST_ANALYZED” la cual puede ser encontrada en vistas tales como: “DBA_TABLES”, “DBA_INDEXES”, “DBA_TAB_COL_STATISTICS” indica la fecha en que fue calculada la estadística para dicho objeto por ultima vez.

     

    Como ejemplo  , si queremos  saber cuando fue la ultima vez que se ejecutaron estadísticas sobre todas las tablas perteneciente a un determinado esquema de BBDD  lanzaremos la siguiente consulta:

    SELECT LAST_ANALYZED,table_name FROM ALL_INDEXES ;

     

     

    Como vemos con las fechas podemos  hacernos una idea , de lo actualizado que están las estadisticas   sobre cada tabla   

    Para actualizar las estadísticas de forma global para  un  esquema de BBDD,  podemos utilizar  el paquete DBM_STATS  de la la siguiente forma:

    Execute DBMS_STATS.gather_schema_stats(‘Esquema’);

     

    Una vez actualizadas las estadísticas de los índices de la base de datos lanzamos la siguiente consulta:

    SELECT LAST_ANALYZED,table_name FROM ALL_INDEXES ;
    SELECT index_name, blevel,
    DECODE(blevel,0,'OK BLEVEL',1,'OK BLEVEL',2,
    'OK BLEVEL',3,'OK BLEVEL',4,'OK BLEVEL','BLEVEL HIGH') OK
    FROM dba_indexes where table_owner='DBPROD08';

     

    Con esta sentencia obtendremos el nombre nombre del índice, el blevel y si es correcto este indice.

    Los índices que deberíamos de reconstruir son los que en la columna ok aparecen como BLEVEL HIGH.

    Blevel (branch level) es parte del formato del B-tree del índice e indica el número de veces que ORACLE ha tenido que reducir la búsqueda en ese índice. Si este valor está por encima de 4 el índice debería de ser reconstruido.

    .

    Extracción de datos de un pdf desde Java


    A veces  necesitamos  extraer información de texto procedente de  ficheros  en formato pdf   por ejemplo  para automatizar la extracción de determinada información  relevante que contengan o simplemente porque deseamos guardar la información editable  en  otro formato mas amigable. En realidad es realmente interesante    intentar   automatizar esta  tarea  pues así nos   evitamos  manipulaciones manuales   y tediosas lo cual seguramente nos hagan perder mucho tiempo  con la gran escasez de este elemento de la vida moderna del que  tampoco disponemos

    Vamos  a ver dos métodos  para hacerlo  usando el IDE  de  Eclipse y el lenguaje Java

    Método 1; mediante un paso intermedio con conversión previa de los ficheros pdf a ficheros de texto

    PDF to TXT Converter es una aplicación de Windows para convertir archivos pdf a archivos de formato de texto sin formato en modo batch. Este programa también admite la conversión de rango de páginas específicas a archivos txt  de modo que después de la conversión, obtendrá el texto editable del documento PDF original

    PDF to TXT Converter

    Esta  utilidad la podemos descargar   desde  aqui

    Hay una pequeña pega con este programa, pues dado que es shareware en la versión gratuita   tiene  bastantes limitaciones ,entre ellas que no se procesaran más de 200 documentos de un sola vez  ( si se intenta con más de esa cantidad   el programa pierde el control)

    Un punto a su favor es que permite convertir automáticamente directorios enteros  con contenido de ficheros pdf y de este modo no necesitamos seleccionar  uno a uno cuál de ellos queremos convertir ( pero no olvide que, a no ser que compre la version completa, solo debería contener como máximo 200  ficheros)

    Como vemos ,lo interesante de este programa  es que permite convertir los  ficheros pdf a texto  lo cual nos facilitara  procesar estos  muy fácilmente desde   java

    Ahora    vamos a   ver un ejemplo    cómo extraer  los metadatos de un documento  de tipo texto obtenido usando el programa anterior

    La idea es que a partir de los pdf convertidos previamente a txt , es que iremos  leyendo el contenidos de cada fichero txt e  interpretando las cadenas extraidas de los pdf para buscar  por ejemplo cuatro  meta-datos que necesitamos , haciendo  cuenta del orden en el que aparecen asi como las palabras justo anteriors:
    -meta1,
    -meta2
    -meta3
    -meta4:

    En esta búsqueda tiene sentido el número de orden en el que aparecen las cadenas anteriores a  la busqueda  pues según el orden en que aparezca corresponderá a un meta-dato u otro.

    En este caso meta2 hay que buscarlo dos veces , pero según este orden la cadena siguiente es meta2 o meta4

    Veamos el ejemplo;

    //*******************************************************
    //BLOQUE PRINCIPAL PARA EXTRAER  4 METADATOS de un fichero
    //*******************************************************

    //abre el fichero
    Scanner in =null;
    DecimalFormat formateador = new DecimalFormat(“####################”);
    Integer contador=0;

    //solo procesaremos los ficheros con la extrension txt
    if (sub.matches(tipofichero)) try{

    in = new Scanner(new FileReader(nombreFichero));
    in.useLocale(Locale.ENGLISH);

    //lee el fichero palabra a palabra

    while (in.hasNext())
    {
    //lee primera palabra
    String palabra = in.next();
    caa=palabra;

    if (procesa==true)
    {
    //System.out.println(“Palabra:”+palabra+ “contador=”+contador);

    if (contador==1)
    {instalacion=palabra;
    }
    if (contador==5)
    {nif=palabra;
    }

    procesa=false;
    contador++;

    }

    if (caa.matches(“pedido:”))
    {
    // System.out.println(“<<<Palabra pedido: ENCONTRADA:>>>”);
    procesan=true;
    contador++;
    }

    if (caa.matches(“instalación:”))
    {
    //System.out.println(“<<<<Palabra instalación: ENCONTRADA:>>>>”);//fecha
    procesa=true;
    contador++;
    }

    if (caa.matches(“NIF/NIE/Pasaporte:”))
    {
    // System.out.println(“<<<<Palabra NIF/NIE/Pasaporte: ENCONTRADA>>>>”);
    procesa=true;
    contador++;
    }

    //lee números
    while (in.hasNextDouble())
    {
    // lee un double

    double d = in.nextDouble();

    if (procesan==true)
    {
    //System.out.println(“Número:”+formateador.format(d)+”contador=”+contador);
    if (contador==3)
    {pedido=d;
    }
    if (contador==7)
    {linea=d;
    }
    procesan=false;
    contador++;
    }

    }

    } // while (in.hasNext())

    //resumen de datos capturados del pdf convertidos en txt y capturada en 4 campos que necesitamos

    System.out.println(“Instalacion:”+instalacion); //fecha
    System.out.println(“Pedido:”+formateador.format(pedido));
    System.out.println(“NIF:”+nif);
    System.out.println(“Telefono:”+formateador.format(linea));

    ….

     

    Método 2  directo usando la Liberia ItextPDF

    iText es una biblioteca Open Source para crear y manipular archivos PDFRTF, y HTML en Java. Fue escrita por Bruno LowagiePaulo Soares, y otros; está distribuida bajo la Affero General Public License.

    El mismo documento puede ser exportado en múltiples formatos, o múltiples instancias del mismo formato. Los datos pueden ser escritos a un fichero o, por ejemplo, desde un servlet a un navegador web.

    Más recientemente, ha sido extendida a una biblioteca PDF de propósito general, capaz de rellenar formularios, mover páginas de un PDF a otro, y otras cosas. Estas extensiones son a menudo mutuamente excluyentes. Una clase te permite rellenar en formularios, mientras una clase diferente e incompatible hace posible copiar páginas de un PDF a otro.

    El soporte de PDF de iText es, sin embargo, bastante extensivo. Esto soporta firmas basadas en PKI de PDF, cifrado de 40-bit y 128-bit, corrección de colores, PDF/X, gestión de colores por perfiles ICC, y es anfitriona de otras característica

    Podemos descargar el fichero itextpdf-5.1.0.jar  desde el respositorio de Maven   o de esta web  http://www.java2s.com/Code/Jar/i/Downloaditextpdf510jar.htm

    No debemos olvidar importar el jar desde el Ide  del  Eclipse   en propiedades del proyecto-->Java Build Path–>libraries –>Add External   JARs

    Este es un ejemplo  de captura sencilla   de como procesar un pdf directaeente

    import java.io.IOException;

    import com.itextpdf.text.pdf.PdfReader;
    import com.itextpdf.text.pdf.parser.PdfTextExtractor;

    public class prueba {

    /**
    * @param args
    */
    public static void main(String[] args) {
    try {

    PdfReader reader = new PdfReader(“d:/ttttt.pdf”);

    System.out.println(“This PDF has “+reader.getNumberOfPages()+” pages.”);
    String page = PdfTextExtractor.getTextFromPage(reader, 1);
    System.out.println(“Page Content:\n\n”+page+”\n\n”);
    System.out.println(“Is this document tampered: “+reader.isTampered());
    System.out.println(“Is this document encrypted: “+reader.isEncrypted());

    reader.close();
    } catch (IOException e) {
    e.printStackTrace();
    }

    }

    }

    Es importante la sentencia String page = PdfTextExtractor.getTextFromPage(reader, 1);  porque si ponemos 0 o un valor superior daría error

    Como   gracias  a la librería podemos capturar la informacion del   fichero pdf y aplicar la clase Sacanne para analizar las cadenas     para buscar determinada  informacion  que queremos catalogar vamos a  ver   el ejemplo anterior  usando los mismos campos  y con la misma casuitica:

    Este seria el mismo ejemplo de la  primer parte  , pero usando directamente los fichero pdf sin convertir a pdf:

    import java.awt.Rectangle;
    import java.awt.print.PageFormat;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintStream;
    import java.io.PrintWriter;
    import java.text.DecimalFormat;
    import java.util.List;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.FileReader;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.util.Scanner;
    import java.util.Locale;
    import java.io.FileNotFoundException;
    import java.nio.charset.StandardCharsets;
    import java.text.DecimalFormat;

    import java.io.StringReader;

    import java.util.Locale;
    import java.util.Scanner;

    import com.itextpdf.text.pdf.PdfReader;
    import com.itextpdf.text.pdf.parser.PdfTextExtractor;

    public class Main {

    /**
    * @param args
    */

    public static void main(final String[] args) throws IOException {

    String instalacion=””;
    String nif=””;
    double pedido=0;
    double linea=0;
    boolean procesa=false;
    boolean procesan=false;
    String tipofichero=”pdf”; // solo tomaremos ficheros con esta extension
    String caa = substring(20);

    String ruta = “D:\temp\ficheros\”;
    String ficherox=”28348758018_20181201000002.pdf”;
    String fichero=ruta+ ficherox;
    System.out.println(“Fichero a analizar =” +ficherox);

    int numero=ficherox.length()-3; //calcula donde empieza la extension del fichero
    // System.out.println(“numero=”+numero);
    String sub =ficherox.substring( numero); //calcula la extension del fichero
    System.out.println(“Extension del fichero :”+sub);

    //abrimos el PDF
    PdfReader reader = new PdfReader(fichero);
    int pages = reader.getNumberOfPages();
    System.out.println(“Este PDF tiene “+pages+” paginas.”);

    //empezamos la coversion a pdf
    String page = PdfTextExtractor.getTextFromPage(reader, 1); ////<———————————————–aqui da errror
    System.out.println(“Contenido del documento de la pagina “+pages);
    System.out.println(“\n\n”+page+”\n\n”);

    /////////////////////////////////////////////////////////////////////
    //solo procesaremos los ficheros con la extrension pdf
    ////////////////////////////////////////////////////////////////////

    if (sub.matches(tipofichero))

    /// try

    {

    //para procesar el texto lo copiamos a una cadena
    String nombreFichero = page ; //Fichero;

    System.out.println(“Convertido salida del conversor a un String “);

    //borra el scanner
    // Scanner in =null;

    //formatos de numeros
    DecimalFormat formateador = new DecimalFormat(“####################”);

    //inicializa conatdor
    int contador=0;

    //in = new Scanner(new FileReader(nombreFichero));///AQUI ESTA EL PROBLEMA PUES SCANNER NO EST ACEPTADNO EL STRING

    Scanner in = new Scanner(nombreFichero);

    in.useLocale(Locale.ENGLISH);
    System.out.println(“Es correcto el pdfl Convertido salida del conversor a un String “);
    //lee el fichero palabra a palabra

    while (in.hasNext()) //leemos toda la cadena
    {
    //lee primera palabra
    String palabra = in.next();
    caa=palabra;

    if (procesa==true)
    {
    //System.out.println(“Palabra:”+palabra+ “contador=”+contador);

    if (contador==1)
    {instalacion=palabra;
    }
    if (contador==5)
    {nif=palabra;
    }

    procesa=false;
    contador++;

    }

    if (caa.matches(“pedido:”))
    {
    // System.out.println(“<<<Palabra pedido: ENCONTRADA:>>>”);
    procesan=true;
    contador++;
    }

    if (caa.matches(“instalación:”))
    {
    //System.out.println(“<<<<Palabra instalación: ENCONTRADA:>>>>”);//fecha
    procesa=true;
    contador++;
    }

    if (caa.matches(“NIF/NIE/Pasaporte:”))
    {
    // System.out.println(“<<<<Palabra NIF/NIE/Pasaporte: ENCONTRADA>>>>”);
    procesa=true;
    contador++;
    }

    //lee números
    while (in.hasNextDouble())
    {
    // lee un double

    double d = in.nextDouble();

    if (procesan==true)
    {
    //System.out.println(“Número:”+formateador.format(d)+”contador=”+contador);
    if (contador==3)
    {pedido=d;
    }
    if (contador==7)
    {linea=d;
    }
    procesan=false;
    contador++;
    }

    }

    } // while (in.hasNext())
    in.close();

    //resumen de datos capturados del pdf convertido en txt

    System.out.println(“Instalacion:”+instalacion); //fecha
    System.out.println(“Pedido:”+formateador.format(pedido));
    System.out.println(“NIF:”+nif);
    System.out.println(“Telefono:”+formateador.format(linea));

    //fin de metatados de un documento INDIVIDUAL en el xml

    }

    }

    private static String substring(int i) {
    // TODO Auto-generated method stub
    return null;
    }//CLASS
    }

     

     

    Con esta librería como vemos  podemos procesar  de un modo relativamente sencilllo   cualquier contenido de un fichero  pdf    de un modo muy potente  como acabamos de ver .

    Shell scripting : variables y operaciones


    Bash , c-shell  o simplemente shell scripting es  un lenguaje de script  creado a fines de la década de 1980 por un programador llamado Brian Fox, que trabajaba para la Free Software Foundation . Fue pensado como una alternativa de software libre para el shell Bourne (de hecho, su nombre es un acrónimo de Bourne Again SHell ), e incorpora todas las características de ese shell, así como nuevas características como la aritmética de enteros y el control de trabajo

    Bash es un “shell de Unix”, es decir  una interfaz de línea de comandos para interactuar con el sistema operativo por lo que está ampliamente disponible, siendo el shell predeterminado en muchas distribuciones de GNU / Linux y en Mac OSX, con puertos existentes para muchos otros sistemas.

    Además del modo interactivo, donde el usuario escribe un comando a la vez, con ejecución y respuesta inmediatas, Bash (como muchos otros shells) también tiene la capacidad de ejecutar un script completo de comandos, conocido como “Bash shell script” (o “Bash script” o “shell script” o simplemente “script”)  que es justo   lo que vamos a tratar en este post como continuación de un  post anterior introductorio donde exponimos ale tipico Hello world en c-shell

    close up code coding computer

    Tuberías y sustitución de comandos 

    Como hemos visto, el valor de retorno de un comando, tomado estrictamente, es solo un pequeño entero no negativo destinado a indicar el éxito o el fracaso. Su salida real es lo que escribe en el flujo de salida estándar. De forma predeterminada, el texto escrito en el flujo de salida estándar se imprime en el terminal, pero hay algunas formas en que se puede “capturar” y usar como el verdadero valor de retorno del comando.

    Tuberías 

    Cuando una secuencia de comandos se vincula entre sí en una tubería, la salida de cada comando se pasa como entrada al siguiente. Esta es una técnica muy poderosa, ya que nos permite combinar varios programas de utilidad pequeños para crear algo complejo.

    Sustitución de comandos 

    La sustitución de comandos es un poco como expansión de variable, pero ejecuta un comando y captura su salida, en lugar de simplemente recuperar el valor de una variable. Por ejemplo, considere nuestro ejemplo de get_password anterior:

    #! / bin / bash
    
    función get_password (  ) 
    # Uso: get_password VARNAME 
    #Le pide al usuario una contraseña; lo guarda como $ VARNAME.
    # Devuelve un estado de salida distinto de cero si la entrada estándar no #es un terminal, o si el comando  "leer" devuelve un estado de salida #tinto de cero.
    
    {
      if [[ -t 0 ]] ; then
        read -r -p 'Password:' -s "$1" && echo
      else
        return 1
      fi
    }
     
    get_password PASSWORD && echo "$PASSWORD"

    Realmente no hay razón para que la persona que llama deba guardar la contraseña en una variable.

    Si get_password simplemente imprimió la contraseña en su salida estándar, entonces la persona que llama podría usar la sustitución de comandos y usarla directamente:

     #! / bin / bash
     
    función get_password (  ) 
    # Uso: get_password 
    # Pide al usuario una contraseña; Imprime para capturar llamando al código. 
    # Devuelve un estado de salida distinto de cero si la entrada estándar no es un terminal, o si 
    # salida estándar * es * un terminal, o si el comando "leer" devuelve un 
    estado de salida distinto de cero #.
     {
      if [[ -t 0 ]] && ! [[ -t 1 ]] ; then
        local PASSWORD
        read -r -p 'Password:' -s PASSWORD && echo >&2
        echo "$PASSWORD"
      else
        return 1
      fi
    }
     
    echo "$(get_password)"
    
    

    Para evaluar "$ (get_password)" , Bash ejecuta el comando get_password en una subshell, capturando su salida estándar y reemplaza $ (get_password) por la salida capturada.

    Además de la notación $ (...) , también se admite una notación más antigua  (con comillas inversas), y aún se encuentra con bastante frecuencia. Las dos notaciones tienen el mismo efecto, pero la sintaxis de  es más restrictiva y, en casos complejos, puede ser más complicado acertar.

    La sustitución de comandos permite anidar como vemos .  Se permite, expresiones  "$ (b" $ (c) ")" . (es decir ,ejecuta el comando c , usando su salida como un argumento para b , y usando la salida de eso como un argumento para a .)

    Una sustitución de comando puede contener una secuencia de comandos, en lugar de un solo comando de modo que se captura la salida de todos estos comandos.

    Como hemos visto anteriormente, se pueden usar puntos y coma en lugar de líneas nuevas para separar los comandos, lo cual  es particularmente común en la sustitución de comandos.

    Una sustitución de comando puede incluso contener asignaciones de variables y definiciones de funciones (aunque, como los comandos sustituidos se ejecutan dentro de una subshell, las asignaciones de variables y las definiciones de funciones dentro del comando no se verán fuera de ella; solo son útiles si se usan dentro de los comandos sustituidos ).

    Aritmética de shell 

    Las expresiones aritméticas en Bash se modelan estrechamente en las de C, por lo que son muy similares a las de otros lenguajes derivados de C, como C ++, Java, Perl, JavaScript, C # y PHP.

    Una diferencia importante es que Bash solo admite aritmética de enteros (números enteros), no aritmética de punto flotante (decimales y fracciones); Por ejemplo  algo como 3 + 4 significa lo que esperarías (7), pero algo como 3.4 + 4.5 es un error de sintaxis. Algo así como 13/5 está bien, pero realiza una división de enteros, por lo que se evalúa en 2 en lugar de en 2.6.

    Expansión aritmética 

    Quizás la forma más común de usar expresiones aritméticas es en la expansión aritmética , donde el resultado de una expresión aritmética se usa como un argumento para un comando

    . La expansión aritmética se denota $ ((...)) . Por ejemplo, este comando:

     echo  $ ((  3  +  4  *  (  5  -  1  )  ))
    

    impresiones 19 .

    expr (en desuso) 

    Otra forma de usar expresiones aritméticas es mediante el programa Unix “expr”, que era popular antes de que Bash admitiera las matemáticas.  Similar a la expansión aritmética, este comando:

     echo  ` expr 3 + 4  \ *  \ (  5 - 1  \)  `
    

    impresiones 19 .

    Tenga en cuenta que el uso de “expr” requiere un carácter de escape “\” antes del operador de multiplicación “*” y los paréntesis. Tenga en cuenta los espacios entre los símbolos de cada operador, incluidos los paréntesis.

    Operadores numéricos

    Además de las notaciones familiares + (adición) y - (resta), las expresiones aritméticas también son compatibles con * (multiplicación), / (división entera, descrita anteriormente), % (división de módulo, la operación “resto”; por ejemplo, 11 dividido por 5 es 2 el resto 1, entonces 11% 5 es 1 ), y ** (“exponenciación”, es decir, involución; por ejemplo, 2 4 = 16, entonces 2 ** 4 es 16 ).

    Los operadores + y - , además de sus sentidos “binarios” (dos operandos) de “suma” y “resta”, tienen sentidos “unarios” (un operando) de “positivo” y “negativo”. Unary + tiene básicamente ningún efecto; unary - invierte el signo de su operando. Por ejemplo, - (3 * 4) evalúa a -12 , y - (- (3 * 4)) evalúa a 12 .

    Referente a variables 

    Dentro de una expresión aritmética, se puede hacer referencia a las variables de shell directamente, sin usar expansión variable (es decir, sin el signo de dólar $ ).

    Por ejemplo, esto:

     i  =  2 +3
     echo  $ ((  7  * i ))
    

    impresiones 35 . (Tenga en cuenta que primero se evalúa i , que produce 5 y luego se multiplica por 7. Si hubiéramos escrito $ i en lugar de i , se habría realizado una mera sustitución de cadenas; 7 * 2 + 3 es igual a 14 + 3, es decir, 17 – Probablemente no sea lo que queremos.

    El ejemplo anterior se muestra usando “expr”:

     i  =  ` expr 2 + 3  ' 
    eco  ' expr 7  \ *  $ i  `
    

    impresiones 35 .

    Asignación a variables 

    Las variables de shell también se pueden asignar dentro de una expresión aritmética. La notación para esto es similar a la asignación de variables regulares, pero es mucho más flexible.

    Por ejemplo, el ejemplo anterior podría reescribirse así:

     echo  $ ((  7  *  (  i  =  2  +  3  )  ))
    

    excepto que esto establece $ i a 5 en lugar de a 2 + 3 .

    Tenga en cuenta que, aunque la expansión aritmética parece un poco a la sustitución de comandos, se no se ejecuta en un subnivel; este comando realmente establece $ i a 5 , y los comandos posteriores pueden usar el nuevo valor. (Los paréntesis dentro de la expresión aritmética son solo el uso matemático normal de paréntesis para controlar el orden de las operaciones).

    Además del operador de asignación simple = , Bash también admite operadores compuestos como + = , - = , * = , / = y % = , que realizan una operación seguida de una asignación. Por ejemplo, ((i * = 2 + 3)) es equivalente a ((i = i * (2 + 3))) . En cada caso, la expresión en su conjunto se evalúa al nuevo valor de la variable; por ejemplo, si $ i es 4 , entonces ((j = i * = 3)) establece tanto $ i como $ j en 12 .

    Por último, Bash soporta operadores de incremento y decremento.

    El operador incremental ++ incrementa el valor de una variable en 1; si precede al nombre-variable (como el operador “pre-incremento”), entonces la expresión se evalúa al nuevo valor de la variable , y si sigue al nombre-variable (como el operador “post-incremento”), entonces la expresión se evalúa al valor antiguo de la variable .

    Por ejemplo, si $ i es 4 , entonces ((j = ++ i)) establece tanto $ i como $ j en 5 , mientras que ((j = i ++)) establece $ i en 5$ j a 4 . El operador de disminución - es exactamente el mismo, excepto que disminuye el valor de la variable en 1. La reducción previa y posterior de la reducción son completamente análogas al incremento previo y al incremento posterior.

    Las expresiones aritméticas como sus propios comandos 

    Un comando puede consistir completamente en una expresión aritmética, usando cualquiera de las siguientes sintaxis:

     ((  i  =  2 + 3  ))
    
     let  'i = 2 + 3'
    

    Cualquiera de estos comandos establecerá $ i en 5 . Ambos estilos de comando devuelven un estado de salida de cero (“exitoso” o “verdadero”) si la expresión se evalúa como un valor distinto de cero, y un estado de salida de uno (“falla” o “falso”) si la expresión se evalúa como cero. Por ejemplo, esto:

     ((  0  ))  ||  echo zero
     ((  1  ))  &&  echo non-zero
    

    imprimirá esto:

    zero
    non-zero

    La razón de este comportamiento contraintuitivo es que en C, cero significa “falso” y los valores distintos de cero (especialmente uno) significan “verdadero”. Bash mantiene ese legado dentro de las expresiones aritméticas, luego lo convierte en la convención habitual de Bash al final.

    El operador de coma 

    Las expresiones aritméticas pueden contener múltiples sub-expresiones separadas por comas , . El resultado de la última sub-expresión se convierte en el valor general de la expresión completa. Por ejemplo, esto:

     echo  $ ((  i  =  2 , j  =  2  + i, i * j ))
    

    establece $ i en 2 , establece $ j en 4 e imprime 8 .

    De hecho , la función incorporada admite múltiples expresiones directamente sin necesidad de una coma; por lo tanto, los siguientes tres comandos son equivalentes:

     ((  i  =  2 , j  =  2 + i, i * j ))
    
     let  'i = 2, j = 2 + i, i * j'
    
     let  'i = 2'  'j = 2 + i'  'i * j'
    

    Operadores de comparación, booleanos y condicionales 

    Las expresiones aritméticas son compatibles con los operadores de comparación de enteros < , > , <= (significado ≤), > = (significado ≥), == (significado =) y ! = (Significado). Cada uno evalúa a 1 para “verdadero” o 0 para “falso”.

    También son compatibles con los operadores booleanos:

    • && (“and”), que se evalúan como 0 si cualquiera de sus operandos es cero, y 1 de lo contrario;
    •  ||(“or”), que se evalúa en 1 si alguno de sus operandos es distinto de cero, y en 0 en caso contrario;
    • ! (“not”), que se evalúa en 1 si su operando es cero, y en 0 en caso contrario.

    Aparte de que utilizan cero para significar valores “falsos” y valores distintos de cero para significar “verdaderos”, son como los operadores && , || , y ! que hemos visto fuera de expresiones aritméticas. Al igual que esos operadores, estos son operadores “abreviados” que no evalúan su segundo argumento si su primer argumento es suficiente para determinar un resultado. Por ejemplo, (((i = 0) &&(j = 2))) no evaluará el (j = 2)parte, y por lo tanto no establecerá $ j en 2 , porque el operando izquierdo de && es cero (“falso”).

    ¿Y soportan el operador condicional b ? e1 : e2 . Este operador evalúa e1 y devuelve su resultado, si b es distinto de cero; de lo contrario, evalúa e2 y devuelve su resultado.

    Estos operadores se pueden combinar de formas complejas:

     ((  i  =  (  ( a> b && c <d + e ||  f  == g + h ) ? j: k )  ))
    

    Aritmética de bucles 

    Arriba, vimos un estilo de for-loop, que se veía así:

    # imprimir todos los enteros del 1 al 20: 
    for i in {1..20} ; do
      echo $i
    done

    Bash también admite otro estilo, modelado en los bucles for de C y lenguajes relacionados, usando aritmética de shell:

    # imprimir todos los enteros del 1 al 20: 
    for (( i = 1 ; i <= 20 ; ++i )) ; do
      echo $i
    done

    Este bucle for utiliza tres expresiones aritméticas separadas, separadas por punto y coma (y no comas , son expresiones completamente separadas, no solo subexpresiones):

    • La primera es una expresión de inicialización, se ejecuta antes de que comience el bucle.
    • El segundo es una expresión de prueba; se evalúa antes de cada posible iteración del bucle (incluida la primera), y si se evalúa a cero (“falso”), entonces el bucle sale.
    • El tercero es una expresión de conteo; Se evalúa al final de cada iteración de bucle. En otras palabras, este bucle for es exactamente equivalente a este bucle while:
    # imprimir todos los enteros del 1 al 20: 
    (( i = 1 ))
    while (( i <= 20 )) ; do
      echo $i
      (( ++i ))
    done

    pero, una vez que se acostumbre a la sintaxis, se hace más claro lo que está sucediendo.

    Operadores bitwise 

    Además de aritméticas y booleanas operadores regulares, Bash también ofrece a los operadores bit a bit “”, significa que los operadores que operan sobre números enteros qua cadenas de bits en lugar de qua enteros.

    Si aún no está familiarizado con este concepto, puede ignorarlo de manera segura.

    Al igual que en C, los operadores bitwise son :

    • & (bitwise “and”),
    • (bitwise “or”),
    • ^ (bitwise “exclusive or”),
    • ~ (bitwise “not”),
    •  << (desplazamiento a la izquierda en modo bit), y
    • >> (desplazamiento a la derecha en modo bit), así como
    •  & =
    •  | =
    • ^ = (que incluyen la asignación, al igual que + = ).

    Literales enteros 

    Una constante entera se expresa como un entero literal . Ya hemos visto muchos de estos; 34 , por ejemplo, es un literal entero que denota el número 34.

    Todos los ejemplos anteriores  han sido decimales (base diez) literales enteros, que es el valor predeterminado; pero, de hecho, los literales pueden expresarse en cualquier base en el rango 2–64, utilizando el valor de base de notación # (la propia base se expresa en base diez).

    Por ejemplo, esto:

     echo $ (( 12 )) # usa el valor predeterminado de base diez (decimal)
     echo $ (( 10 # 12 )) # especifica explícitamente base diez (decimal)
     echo $ (( 2 # 1100 )) # base dos (binario)
     echo $ (( 8 # 14 )) # base ocho (octal)
     echo $ (( 16 # C )) # base dieciseis (hexadecimal)
     eco $ (( 8 + 2 # 100 )) # ocho en base diez (decimal), más cuatro en base dos (binario)
    

    Imprimirá 12 seis veces. (Tenga en cuenta que esta notación solo afecta a cómo se interpreta un literal entero. El resultado de la expansión aritmética todavía se expresa en base diez, independientemente).

    Para las bases 11 a 36, ​​las letras inglesas A a Z se usan para los valores de dígitos 10 a 35. Esto no distingue entre mayúsculas y minúsculas. Sin embargo, para las bases 37 a 64, son las letras inglesas en minúsculas las que se usan para los valores de dígitos 10 a 35, mientras que las letras mayúsculas se usan para los valores de dígitos 36 a 61, el signo at @ se usa para las cifras el valor 62, y el subrayado _ se usa para el valor de dígitos 63. Por ejemplo, 64 # @ A3 indica 256259 ( 62 × 64 2 + 36 × 64 + 3 ).

    También hay dos notaciones especiales: el prefijo de un literal con 0 indica la base ocho (octal), y el prefijo de 0x o 0X indica la base dieciséis (hexadecimal). Por ejemplo, 030 es equivalente a 8 # 30 , y 0x6F es equivalente a 16 # 6F .

    Variables enteras 

    Una variable se puede declarar como una variable entera, es decir, su “atributo entero” se puede “establecer”, usando esta sintaxis:

    declare -i n
    Después de ejecutar el comando anterior, cualquier asignación subsiguiente a n hará que el lado derecho se interprete automáticamente como una expresión aritmética. Por ejemplo, esto:
    declare -i n
    n='2 + 3 > 4'
     Es más o menos equivalente a esto:
     n  =  $ ((  2  +  3 > 4  ))
    

    excepto que la primera versión declare -incontinuará afectando las tareas posteriores también.

    En la primera versión, note el uso de comillas en el lado derecho de la tarea. Si hubiéramos escrito n = 2 + 3> 4 , habría significado “ejecutar el comando + con el argumento 3 , pasando la variable de entorno n configurada a 2 y redirigiendo la salida estándar al archivo 4 “; es decir, establecer el atributo entero de una variable no afecta el análisis global de las declaraciones de asignación, sino que simplemente controla la interpretación del valor que finalmente se asigna a la variable.

    Podemos “anular” el atributo entero de una variable, desactivando este comportamiento, usando el comando opuesto:

    
    
    declare +i n

    El comando declare incorporado también tiene otros usos: hay algunos otros atributos que una variable puede tener, y declare tiene algunas otras características además de activar y desactivar los atributos. Además, algunas de sus propiedades destacan:

    • Al igual que con local y export , el argumento puede ser una asignación de variable; por ejemplo, establece el atributo entero de $ n y lo establece en 5 .declare -i n = 2 +3
    • Al igual que con local y export , se pueden especificar múltiples variables (y / o asignaciones) a la vez; por ejemplo, declare -i n=2+3 establece tanto el atributo entero de $ m como el de $ n .
    • Cuando se usa dentro de una función, declare implícitamente localiza la variable (a menos que la variable ya sea local), lo que también tiene el efecto de desarmarla localmente (a menos que se use la sintaxis de asignación).

    Aritmética no entera 

    Como se mencionó anteriormente, Bash shell arithmetic solo admite aritmética de enteros. Sin embargo, los programas externos a menudo se pueden usar para obtener una funcionalidad similar para valores no enteros.

    En particular, la utilidad de Unix común bc se usa a menudo para esto. El siguiente comando:

     echo  "  $ (  echo  '3.4 + 2.2'  | bc )  "
    

    impresiones 5.6 .

    No hace falta decir que, dado que bc no está tan estrechamente integrado con Bash como lo es la aritmética de shell, no es tan conveniente; por ejemplo, algo como esto:

    # imprimir las potencias de dos, de 1 a 512: 
    for (( i = 1 ; i < 1000 ; i *= 2 )) ; do
      echo $i
    done

    sería, para soportar no enteros, convertirse en algo como esto:

    # imprimir los poderes de la mitad, de 1 a 1/512: 
    i=1
    while [ $( echo "$i > 0.001" | bc ) = 1 ] ; do
      echo $i
      i=$( echo "scale = scale($i) + 1 ; $i / 2" | bc )
    done

    Parte de esto se debe a que ya no podemos usar un aritmética for-loop; parte de esto se debe a que hacer referencia a las variables y asignarlas a las variables es más complicado ahora (ya que bc no es consciente de las variables de la shell, solo de las suyas, no relacionadas); y parte de ello se debe a que bc se comunica con el shell solo a través de entrada y salida.

    !Y  esto  es todo por hoy!Pero no se preocupe en proximos post trataremos otrso temas como entrada/salida, funcionaes complejas y mucho mas

    Mas informacion en  https://en.wikibooks.org/wiki/Bash_Shell_Scripting

    Editar ficheros con linux


    Para muchas personas, una de las piezas de software más importantes es un procesador de textos, aunque obviamente si ese equipo es un Linux  para  escribir documentos se usen otros programas como LibreOffice Writer,Open Office ,ete c o incluso servicios en linea como google docs , un editor de texto, sigue siendo hoy en dia  una herramienta indispensable  pera  ver contenido de ficheros ASCIII ( por ejemplo tipo logs, txt ,etc )   y también  para editar o ver  scripts de shell, programas PostScript, páginas web y más.

    Un editor de texto opera en archivos de texto sin formato almacenando solo los caracteres que escribe no agregando ningún código oculto de formateo. Es decir ,si escribimos unos caracteres   y presionamos Enter en un editor de texto y lo guardamos, el archivo contendrá exactamente esos caracteres y una nueva línea. Sin embargo si usamos  un  procesador de textos, dicho fichero  que contenga el mismo texto sería miles de veces más grande (con abiword por ejemplo un archivo de unos pocos caracteres  podiria ocupar 2.526 bytes, el archivo LibreOffice.org contendria sobre 7.579 bytes).

    Puede escribir scripts en cualquier editor de texto, desde el e3 básico o nano hasta el emacs o nedit completos.

    Los mejores editores de texto le permiten tener más de un archivo abierto a la vez. Hacen que el código de edición sea más fácil con, por ejemplo,con  resaltado de sintaxis, sangría automática, autocompletado, revisión ortográfica, macros, búsqueda y reemplazo, y la importante funcion de deshacer.

    En última instancia, qué editor se  elige es una cuestión de preferencia personal pero en  GNU  uno muy bueno  es  emacs

    emacs1.PNG

    Emacs viene autodocumentado de serie con un manual al que puede acceder usando el comando info. Ya sea desde una terminal de los sistemas operativos GNU y Unix, o desde el propio Emacs, escribiendo M-x info RET (esto quiere decir Meta- x o ESC x, la palabra “info”, seguido de la tecla return), o escribiendo C-h i (eso es Control-h seguido de la i). Ademá Emacs trae consigo un tutorial interactivo que le guiará paso a paso a través de una sesión de edición en la cual aprenderá los elementos básicos del uso de Emacs como editor de texto.

    Para realizarlo, proceda de la siguiente manera:

    • Utilice C-h t (presione Control y h, suelte ambas teclas, y luego pulse t).
    • Si eso no resulta, intente mediante F1 t.
    • Si eso no resulta tampoco, intente M-x help-with-tutorial (Pulse Esc, suéltela, pulse x, suéltela, escriba help-with-tutorial, pulse Enter).

    Si desea leer el tutorial en un idioma distinto al Inglés, use el comando M-x help-with-tutorial-spec-language. (en el momento se encuentran disponibles: bg, cn, cs, de, es, fr, it, ja, ko, nl, pl, ro, ru, sk, sl, sv, th, zh  , es decir también esta en español)

    Las opciones más habituales:

    • Obtener ayuda C-h (Mantenga presionada la tecla CTRL y presione h)
    • Deshacer cambios C-x u Salir Emacs C-x C-c
    • Obtener un tutorial C-h t Usar información para leer documentos C-h i
    • Manuales de pedido C-h RET
    • Activar la barra de menú F10 o ESC `o M-`
    • `C- ‘significa usar la tecla CTRL.
    • ` M-‘ significa usar la tecla Meta (o Alt).Si no tiene una clave Meta, en su lugar puede escribir ESC seguido del carácter).

    El entorno puede modificar el modo en que secuencias como C-h o F1 son interpretadas.

     

    Cuadro de Referencia Resumido

    Apertura de archivos: C-x C-f – luego escriba el nombre del archivo, puede usar la tecla TAB para  autocomplementar de modo automático.

    Creación de nuevos documentos: C-x C-f – luego escriba el nombre de un archivo que no exista aun; use TAB para  autocomplementar de modo automático.

    Guardar archivo: C-x C-s

    Destruir búfer (cerrar archivo): C-x k

    Separar ventanas (para ver dos archivos al mismo tiempo):

    • Una sobre la otra: C-x 2
    • Una al lado de la otra: C-x 3

    Unificar ventanas (maximizar una ventana)C-x 1

    Cambiar de ventana (luego de haber hecho una separación): C-x o

    Cambiar de búfer (si está editando múltiples archivos): C-x b

    Menú de búferes (listado de búferes): C-x C-b

    Ejecutar comandos de cuyo atajo por teclado se ha olvidado: M-x – luego escriba el nombre del comando, TAB puede ser usado para autocomplementar.

    Obtener ayuda: C-h, luego cualquiera de las siguientes teclas:

    • k – ¿qué hace cierta secuencia de teclado?
    • f – ¿qué hace cierta función?
    • m – ¿qué secuencias de teclado están definidas en este modo?
    • w – ¿a qué teclas está asociada una función?
    • a – ¿qué nombres de comandos coinciden con cierta cadena?

     

     

    Como ve, emacs  es un editor  ASCII  muy diferente a los editores basados en sistemas windows , pero como se ve tambien puede ser muy potente para trabajar desde una consola depurando o inlcuso escribiendo nuestros propios scripts en c-shell

    Sistema de reconocimiento de colores para personas con discapacidades visuales


    ColorDec  es un interesantismo  proyecto  que representará  al colegio Lope de Vega de 3ª de el ESO  para el concurso RetoTech que organiza ENDESA    creado por   Esther Scott, Irene Yebra, Irene Jimenez,Lucia Gomez y Paula  Vidal  ,  con el propósito de   ayudar  a  personas con discapacidad  visual para  mejorar su percepción de los colores,  gracias  a un hardware de bajo coste basado en Arduino   y una aplicación móvil  que ellas mismas han escrito usando el Mit App Inventor, una herramienta de la que por cierto hemos hablado en numerosas ocasiones en este blog .

    El proyecto  tiene  pues su base  en un Arduino Nano, al que le han acoplado  un modulo bluetooth  para el envío de datos a  un smartphone  mediante los pines 9 (Rxd)  , 8(Txd)  para los datos  vía serie,   así como  VCC y gnd para la alimentación desde Arduino al  propio modulo  Bluetooth.

    Para el reconocimiento de colores cuenta con un sensor especializado como es  el GY33 ( unos 15€ en Amazon)  el cual conectan al propio Arduino via I2C  por los pines A4,A5  alimentándose desde el propio Arduino  desde los pines  5v y GND.

    El  GY-33 es un modulo  de reconocimiento de color de bajo costo que puede alimentarse  entre  3-5 V, con bajo consumo de energía, de  tamaño pequeño y facilidad de instalación.
    Su principio de funcionamiento radica en que la iluminación de la irradiación de luz LED debe medirse  hacia el objeto de modo que la  luz de retorno es  detectada por los filtros de valores RGB y el propio modulo identifica los colores según los valores RGB.
    Este módulo, soporta dos maneras de envió de  datos:

    • Via serie,  es decir mediante UART en serie (nivel TTL) configurando la conexión a 9600bps y 115200bps  siendo la velocidad en baudios del puerto en serie  configurable.
    • I2C (mediante 2 líneas) que es el que han empleado en este circuito mediante  lso pnes A4 y A5 .

    El modulo puede hacer  un reconocimiento simple de 7 colores y no es necesario calcular el valor RGB o se puede gestionar  el dato de una manera compleja como vamos a ver.

    Se complementa  el circuito   final con un pulsador(pin2)  con su respectiva resistencia para evitar rebotes    y la alimentación de  todo el conjunto  por un pila de 9v desde los pines VIN y GND de Arduino.

    El diagrama   final  lo  podemos ver en  la imagen de mas abajo:

     

    esquema

     

    El dispositivo esta pensado para ser portátil de modo que sujetándolo con una mano se apoya en el objeto del que se  desea conocer el color , se pulsa el botón para que este lo transmita (tras convertirlo de RBG a HSV) por bluetooth al teléfono móvil del usuario, desde donde una APP   lo  reproduce hablando en inglés o castellano.

    En cuanto al software para este  proyecto ha sido realizado utilizando el IDE de Arduino para programar un Arduino Nano, al que se le ha conectado un módulo Bluetooth, un Pulsador y un módulo GY-33 para el reconocimiento de color  lo cual es tarea del firmware de Arduino gestionarlo

    El programa del Arduino, en su inicialización realiza un balance de blanco, y después espera a que se pulse el pulsador para leer el color, convertirlo a HSV y enviarlo por Bluetooth al móvil.

    El código provisional para el firmware de Arduino que aun esta es proceso de mejora  nos lo comparten en estas lineas:

     

    Colorview4-ino_1.png

    Colorview4-ino_2.png

    Colorview4-ino_3

    Ya desde el teléfono, se conecta al Arduino por Bluetooth, se cargan dos arrays con los datos de dos ficheros CSV, uno con los códigos RGB de los colores y otro con los nombre de esos colores .

    Se busca el color en el array y si se encuentra ese será el que el teléfono lea en voz alta.

    Sino se encuentra entre los más de 600 códigos RGB, se usa el código en HVS para construir una frase que describe como es el color y se envía al sistema de síntesis de voz del teléfono.

    La conversión a HVS han tenido que hacerla al no poder ordenar los códigos RGB para poder situarse sobre el color más cercano al leído.

    Amablemente nos han compartido sin código escrito con el MIt App Inventor  para desplegarlo en un terminal Android

     

    App-Inventor-Blocks 2-page.png

     

    Es sin duda  un sistema  de mínimo coste  que puede ser de muchísima ayuda para  identificar  los colores para personas con deficiencias visuales,  así que le deseamos desde este blog  toda la suerte posible . El premio es una plaza para cada una de las cinco en un campamento de verano donde seguirán aprendiendo robótica y programación , así que queridos lectores porfavor  si os parece interesante  todo el esfuerzo de esta   chicas y  merece vuestra confianza, esta es la dirección para  votar   su proyecto:

    https://pr.easypromosapp.com/voteme/826101/630232517

    Personalmente  ya he votado porque me ha parecido impresionante el trabajo realizado , así que desde esta lineas  les deseamos toda la suerte en este concurso  y ojala puedan seguir aprendiendo  y perfeccionando sus conocimientos  tecnicos de modo que puedan seguir ayudando a construir un mundo mucho mejor gracias al uso de la tecnología y su ingenio

    Programar Arduino con Eclipse


    Arduino es una plataforma de prototipado electrónica de código abierto basada en software y hardware flexible y fáciles de usar. Está destinado a artistas, diseñadores, aficionados y cualquiera interesado en la creación de objetos interactivos o entornos.
    En realidad el Arduino es un montón de cosas. Dado un determinado contexto, puede significar cualquiera de las siguientes…

    • Arduino , la plataforma de hardware (el «Consejo»)
    • Arduino – la biblioteca de abstracción sobre el WinAVR. WinAVR es la cadena de herramientas GNU (compilador + C Runtime library etc.) para el Microcontrolador AVR utilizado en las placas de Arduino (el “software”)
    • Arduino – “El IDE” (estamos utilizando Arduino 19)

    Para empezar con Arduino antes de nada se  necesita familiarizarse con la plataforma Arduino y jugar con el IDE de Arduino que es libremente descargable desde la Web de Arduino.

    Si es un  programador experto , pronto se dará cuenta   que necesita  un más potente conjunto de herramientas como puede ser  la combinación de WinAVR , biblioteca Arduino + Eclipse y esto es lo que vamos a ver en este post.

     

    leds arduino

    Instalación  IDE

    Sucintamente  los pasos para  programar Arduino con el Eclipse son los siguientes:.

    1. Descargar Eclipse (sobre 90 MBs). Descomprimir en C:\Misc\Eclipse
    2. Descargar el IDE de Arduino. Descomprimir en C:\Misc\arduino-0019
    3. Descargar la última versión de WinAVR. Descomprimir en C:\Misc\WinAVR
    4. Descargar el Plug-in de Eclipse de AVR e instalarlo (siga las instrucciones en su página web)

    Primeros pasos con Eclipse

    1. Iniciar Eclipse
    2. Cerrar la página de bienvenida haga clic en la Cruz en la ficha para revelar el ambiente de trabajo real…
    3. Comenzar un nuevo proyecto haciendo clic en “archivo -> Nuevo -> proyecto de C++“. Elegir el tipo de proyecto “AVR Cross Target biblioteca estática” y establezca el nombre del proyecto Arduino. Ahora vamos a compilar los archivos fuente de Arduino en una biblioteca estática para su uso posterior. Finalmente haga clic en finalizar.
    4. Utilice el explorador de Windows para ir a C:\Misc\arduino-0019\hardware\arduino\cores\arduino, seleccionar todos los archivos de código y arrastrar sobre el proyecto de Arduino ya abierto en Eclipse( Nota :sólo incluyen archivos con extensiones .c, .cpp y .h …)
    5. A continuación, haga clic en aceptar en el siguiente cuadro de diálogo (aceptar la opción de copia por defecto)…
    6. Ahora construya el proyecto haciendo clic derecho sobre él y eligiendo “Crear” en el menú contextual. !puede  que tengamos mas de 10 errores! Pero no se preocupe, a arreglarlos en el momento. Haga clic derecho sobre el proyecto y elija “Propiedades” e ir a la opcion “c/c ++ Build -> Configuración -> AVR compilador” . Haga clic en el icono “+” (después de seleccionar la opción “Directorios”).
    7. Haga clic en el botón “Área de trabajo...” y añadir el directorio del proyecto ${workspace_loc :/ ${Nombre_proyecto}} como un directorio de inclusión una vez para el “compilador AVR” y el “AVR C++ Compiler”
    8. Haga clic derecho sobre el proyecto y elija “Propiedades“, luego ir a “AVR -> Target Hardware” y luego establecer la opción de tipo de MCU en el microprocesador en la placa Arduino junto con la frecuencia del cristal suministrado con él. Por  ejemplo para un arduino antiguo  que lleve el ATmega328P  el valor es de  16000000 respectivamente. A continuación, haga clic en ok.
    9. Ahora construya su proyecto de nuevo  de modo qeu  la construcción debería tener éxito esta vez.(Aunque es posible que vea un montón de advertencias que, simplemente puede ignorarlos por ahora).

    Ejemplo

    1. Es hora de que el equivalente a “Hola mundo” el mundo de sistemas embebidos. Ir a “archivo -> Nuevo -> proyecto de C++” como antes pero ahora seleccione “AVR Cross Target solicitud” como el tipo de proyecto y establezca el nombre del proyecto a “social
    2. Haga clic derecho sobre el proyecto social y elegir “New -> File”, el nombre del archivo a Main.cpp y haga clic en finalizar.
    3. Ahora, agregue el código siguiente de C++ a Main.cpp:
      #include "WProgram.h" //Include arduino headers
      
      ///CONSTANTS///
      //The onboard test LED is connected to pin number 13
      const int ledPin = 13;
      const int interval = 1000; //Milliseconds
      
      ///MAIN///
      int main()
      {
          //Initialize the Arduino library.
          //Not doing so will prevent the delay function
          //from working. Calling this functions is a must
          //for all arduino projects.
          init();
      
          //Initialize the serial port. This will be used
          //to send diagnostic information in this project.
          Serial.begin(9600);
      
          //Configure ledPin as an output
          pinMode(ledPin, OUTPUT);
      
          //Announce the start of program. Usually a
          //hyper-terminal is connected to the serial
          //port on the PC so this message can be seen
          //there
          Serial.println("Ready.");
      
          //Enter the infinite loop responsible for making
          //the microcontroller do the same thing over and
          //over again. (Almost every microcontroller has
          //such a loop)
          while(true)
          {
              //Turn on the LED
              digitalWrite(ledPin, HIGH);
              //Wait for half of "interval".
              //The LED remains ON during this time.
              delay(interval/2);
              //Turn off the LED
              digitalWrite(ledPin, LOW);
              //Wait for half of "interval".
              //The LED remains OFF during this time.
              delay(interval/2);
          }
      
          //Unreachable code but it's required by
          //the compiler
          return 0;
      }
    4. Ahora compile el proyecto. !es posible que tenga  un montón  de errores!
    5. OK vamos a arreglarlos. Haga clic derecho sobre el proyecto de “Social” y elija “Propiedades” e ir a la “construcción de C/C++-> Configuración -> Avr Compiler -> directorios” opción y haga clic en el icono “+”.
    6. Haga clic en el botón “área de trabajo…” en el cuadro de diálogo subsecuente y elija Arduino -> Debug en el cuadro de diálogo el posterior.
    7. Finalmente se debe ver la siguiente. Haga clic en Aceptar después de haber verificado la ruta.
    8. Hacer lo mismo para la “construcción de C/C++-> Configuración -> Avr C++ Compiler -> directorios”
    9. Ir a “construir de C/C++-> Configuración -> Avr C++ linker -> bibliotecas” y defina las siguientes opciones.
    10. Ahora compilar el proyecto social otra vez. Compruebe que es mucho mejor ahora, pero todavía tenemos un error . Esto es un error de vinculador. El vinculador se queja aquí que no podría encontrar una aplicación para la función de llamada en cualquier lugar aunque se refiere a / usado en otras partes del código. Baste decir la función es necesaria por el runtime de C++ para decidir lo que hay que hacer cuando alguien llama a una función virtual pura directamente. Como recordará de sus tratos con C++, una función virtual pura no se puede llamar directamente sin proporcionar una implementación en alguna clase derivada. Para ello, una clase con una función virtual pura no puede ser instanciada en todos pero el runtime de C++ le gusta estar preparado para cualquier eventualidad.Compiladores avanzados habrían lanzado una excepción de esta función para indicar una operación ilegal, pero como no tenemos los de la plataforma de WinAVR, todo lo que podemos hacer es evitar  más daño que está haciendo entrar en un bucle sin fin (suponiendo que el programa es corriendo frenéticamente en primer lugar ya que ha hecho lo imposible por llamar a una función virtual pura directamente!)
      Nota: esto debe hacerse sólo para la versión de depuración. Al parecer esta función no se utiliza en la versión de lanzamiento de Arduino. Las compilaciones de depuración están amañadas para fallar rápidamente para que el punto de falla es lo más cercano posible al lugar donde está el verdadero problema.
    11. Agregar un nuevo archivo .c al proyecto Arduino (Nota debería ser .c y no CPP). Llame al missing.c y pegue el código siguiente en él y construir de nuevo ambos proyectos. El error debería desaparecer. Tenga en cuenta que lo necesario para construir Arduino antes de poder construir social.
      void __cxa_pure_virtual()
      {
          while(1);
      }
    12. Conmutando el panel de “Consola”, puede ver el resultado de ejecutar el comando tamaño de avr en el archivo .elf de generado…Pero no es un bonito espectáculo para la vista. Un pobre programa intermitente led ocupa aproximadamente 62% del total de memoria de programa disponible. Pero no se asuste, estamos en la versión de depuración  de modo que obtendrá mejores resultados al cambiar a liberar estructuras.

    Cambiar a la versión de lanzamiento

    1. Haga clic derecho en un proyecto y seleccione “configuraciones de generación -> Set activo -> Release 2”. Hacer esto para todos los proyectos.
      Nota: usted necesita volver a especificar todos los ajustes para la versión de lanzamiento como hiciste para hacerlo compilar la versión de depuración.

    Optimización prematura

    1. Aquí es cómo vamos de mejor a impresionantes. A continuación se asegurará de que usted sólo paga por las funciones y secciones de datos que realmente se utilizan en el programa. Agregue los siguientes indicadores adicionales para el C y C++ compiladores en todos los proyectos
      -ffunction-sections -fdata-sections

      Añadir la siguiente bandera a las opciones del vinculador en todos los proyectos.

      -Wl,-gc-sections

       

    2. Reconstruir (en el correcto orden Arduino en primer lugar, social segundo.)

    Cargar el programa en el Arduino

    Ahora ha llegado el momento cuando usted puede cargar su primer programa de Arduino construido dentro de los confines cómodos de Eclipse.

    1. Haga clic derecho sobre el proyecto social y selecciona “Propiedades“. Ir a la página de AVRDude y haga clic en nuevo.
    2. Rellene el formulario siguiente:
      • Nombre de configuración: Arduino
      • Hardware del programador: Arduino
      • Reemplazar el puerto por defecto: \\.\COM3. Reemplazar el COM3 a cualquier puerto del hardware de Arduino está conectado a.
      • Override en baudios por defecto: 19200. Reemplazar 19200 a cualquier velocidad en baudios fue especificado por el fabricante del tablero / la persona que subido el Arduino boot loader en tu tarjeta.

       

    3. Seleccionar Arduino como programador en AVRDude configuración y haga clic en Aceptar.
    4. Haga clic en el botón de la barra de herramientas AVR para subir su programa a la placa.

      Debería ver algo como lo siguiente en la ventana de la consola…

      Launching C:\misc\WinAVR\bin\avrdude -pm328p 
          carduino "-P\\.\COM3" -b19200 -Uflash:w:BlinkenLights.hex:a 
      Output:
      
      avrdude: AVR device initialized and ready to accept instructions
      
      Reading | ################################################## | 100% 0.02s
      
      avrdude: Device signature = 0x1e950f
      avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
               To disable this feature, specify the -D option.
      avrdude: erasing chip
      avrdude: reading input file "BlinkenLights.hex"
      avrdude: input file BlinkenLights.hex auto detected as Intel Hex
      avrdude: writing flash (2828 bytes):
      
      Writing | ################################################## | 100% 2.16s
      
      avrdude: 2828 bytes of flash written
      avrdude: verifying flash memory against BlinkenLights.hex:
      avrdude: load data flash data from input file BlinkenLights.hex:
      avrdude: input file BlinkenLights.hex auto detected as Intel Hex
      avrdude: input file BlinkenLights.hex contains 2828 bytes
      avrdude: reading on-chip flash data:
      
      Reading | ################################################## | 100% 2.14s
      
      avrdude: verifying ...
      avrdude: 2828 bytes of flash verified
      
      avrdude done.  Thank you.
    5. Si todo salió bien, la prueba a bordo del LED (generalmente color rojo) ahora si empieza a parpadear en cerca de 1 parpadeo/seg Felicitaciones!

    Finalmente hemos visto cómo utilizar Eclipse para el desarrollo de AVR. Pero esto es sólo el principio pues hay mucho explorar pero hemos visto  los fundamentos y ahora debería ser fina por su cuenta. Los ejemplos y bibliotecas suministradas con Arduino deben ser un buen punto de partida para la exploración de más.

     

     

    Fuente https://www.codeproject.com/Articles/110859/Arduino-Unleashed