27/11/17

Scrapping con C#. Listas de Contratación Temporal de la Xunta.

url es la variable con la url a scrapear //valga el palabro

"//td[@align='left']" es una expresión xpath que devolvería los TD con alineación izquierda

Para hacer el scrapping con cSharp usamos ScrapySharp

Hay ejemplo completo en GitHub aquí

Código:

ScrapingBrowser Browser = new ScrapingBrowser();
Browser.UserAgent = new FakeUserAgent("primero", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0");
Browser.AllowAutoRedirect = true; // Browser has settings you can access in setup
Browser.AllowMetaRedirect = true;
WebPage PageResult = await Browser.NavigateToPageAsync(new Uri(url));
IEnumerable TDs = PageResult.Html.SelectNodes("//td[@align='left']");
this.lNombre.Clear();
foreach (HtmlNode item in TDs) {
    this.lContenidosTDs.Add(item.InnerText);
}

22/11/17

Comprobación de Consulta das Listas de Vinculación Temporal Decreto 37/2006. Javascrip

Está también en Github

const fileName = "./personas.json";
const Horseman = require("node-horseman");
const cheerio = require('cheerio')
const fs = require('fs');

var horseman = new Horseman();

var Personas = [];
var PersonasAnteriores;
var grabarFichero = false;

function GestionDeParametros(params){
if(params.length == 3){// así es que se envía un parámetro
grabarFichero = true;
}
}
function getPersonas(body) {
var $ = cheerio.load(body);
//$(".taboadatos TD");
var columna = 0;
$('.taboadatos TD').each(function () {
columna++;
if (columna === 1) {
Personas.push($(this).text());
}
if (columna === 4) {
columna = 0;
}

});
if(grabarFichero){
fs.writeFileSync(fileName,JSON.stringify(Personas),'utf-8');
}
var i = 0;
console.log("LISTA DE CAMBIOS DE LAS LISTAS DEL B SEGÚN FICHERO: " + fileName);
console.log("===================================================");
Personas.forEach(element => {
if (element === PersonasAnteriores[i]) {
console.log("" + (i + 1) + ": (IGUALES) " + element);
} else {
console.log("" + (i + 1) + ": (DIFERENTES) " + element + '///' + PersonasAnteriores[i]);
}
i++;
});
}

function ShowPersonas(per) {
console.log(per);
}

function CargarPersonasAnteriores() {
try {
PersonasAnteriores = JSON.parse(fs.readFileSync(fileName, 'utf-8'));
} catch (err) {
console.error(err);
console.error("No existe el fichero generelo con: ***");
}
}

GestionDeParametros(process.argv);
CargarPersonasAnteriores();

horseman
.userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0")
.open('http://www.xunta.es/rcp/listas/rcp_li05/li05_lista_ambito_sel.jsp?rcpCOD_LISTA=76&rcpCOD_AMBITO=U0000&rcpDES_AMBITO=AMBITO%20AUTON%D3MICO&lang=gl')
.waitForSelector("TD")
.html()
.then(function (body) {
getPersonas(body)
horseman.close();
})
;

20/11/17

Test. Clase de ayuda para envío de pulsaciones de teclas.

SSk: Static Send Keys.

Es un envoltorio para facilitar el uso de la función "SendKeys.SendWait(string keys)" y algunas utilidades más como introducir un tiempo de espera entre pulsación y pulsación. También permite generar apropósito tiempo de espera (Tread.Sleep(miliseconds)) y facilita el envío de algunas teclas especiales.

Se encuentra en github como parte del proyecto Utils pero es, de momento, muy independiente y no necesita nada del resto del proyecto.

https://github.com/IvanCruzFraguela/UtilNs/blob/master/Test/SSk.cs

28/9/17

SqlServer. Asociar usuarios de Directorio Activo a Base de Datos.

Hay que estar en la Base de Datos:

use DatabaseName;
Luego hay que crear el usuario para la base de datos:
create user [dominio\usuarioOGrupo];

Se me hace extraña la notación entre corchetes pero es así. Hay que poner el corchete, dominio, barra invertida, usuario o grupo AD y corchete.

Una vez que el usuario ya lo tiene en cuenta SqlServer, hay que decirle para qué lo vamos a usar. Se pueden dar todo tipo de permisos por tabla y/o columna pero lo típico será asignarlo a uno de los roles que tenga la Base de datos.

alter role [db_datareader,db_datawriter,...] add member [dominio\usuarioOGrupo];

En este caso los primeros corchetes no se ponen, son para definir que hay que elegir alguno de los roles. Por ejemplo:

alter role db_datawriter add member [empresa\vendedores];

Esto daría permiso de escritura en la Base de Datos activa a los pertenecientes al grupo vendedores en nuestro dominio (empresa)

Con esto, los pertenecientes a un grupo de Directorio Activo podrán, por ejemplo, escribir en una base de datos. Una vez que a ese usuario de dominio se le quita del grupo, ya no podrá hacerlo.

21/9/17

Operaciones con campos Identity (SqlServer)

Muchas de las tablas que uso tienen campos autonuméricos, llamados Identity, en SqlServer.

Si necesitamos introducir un número específico en esos campos, por ejemplo, porque estemos copiando una tabla de otra base de datos, o queramos tener unos valores específicos en algunos registros, tenemos que parar esa inserción antes de hacerlo.
Para ello usamos el comando:
set identity_insert [tabla] off;
set identity_insert [tabla] on; // Para dejarlo como estaba
Es importante tener en cuenta que SqlServer solo permite parar una inserción a la vez por Base de Datos. No podríamos tener dos tablas con la inserción parada. Habría que parar una, hacer las operaciones correspondientes, dejarla con la inserción activa de nuevo, y entonces parar la siguiente.
Tras esto, para fijar el valor en el que queramos que siga la inserción (normalmente igual al mayor número insertado hasta ahora) habría que ejecutar el comando:
DBCC CHECKIDENT ('[tabla]', RESEED,[numeroapartirdelcualsumar1]);

20/6/17

SqlServer. Lista de tablas y tablas relacionadas (Foreing key)

Lista de tablas
select * from sys.all_objects where type like 'U'

Tablas relacionadas con una dada.
SELECT   
   distinct OBJECT_NAME (f.referenced_object_id) AS referenced_object  
   FROM sys.foreign_keys AS f  
   WHERE f.parent_object_id = OBJECT_ID('[Nombre_tabla]');

15/5/17

Otro de envío de teclas.

Ejecuta un chrome y le envía las teclas para probar la página

Parece funcionar. Habría luego que comprobar que la página ha hecho lo que se le ha pedido



Process p = new Process();
p.StartInfo.FileName = @"C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe";
p.StartInfo.Arguments = @"file:///C:/Users/usuario/Desktop/borrame.html";//html que se quiere probar
p.Start();
p.WaitForInputIdle();
Thread.Sleep(1000);
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("hola a todos");
SendKeys.SendWait("{Tab}");
SendKeys.SendWait("{Enter}");
Thread.Sleep(1000);
p.CloseMainWindow();

Lectura de datos de usuario de directorio activo a un fichero.

Está también en github aquí
using System;

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.IO;

namespace udaExe {
    class Program {
        static void Main(string[] args) {
            string ldapEntry;
            string fileName;
            int cantUsuarios = 0;
            if (!GetParameters(args, out ldapEntry, out fileName)) {
                Console.Out.WriteLine("uso: udaExe ldap fichero");
                Console.Out.WriteLine("Ejemplo: udaExe \"LDAP://OU=Users,dc=microsoft,dc=local\" \"c:\\usuarios.txt\"");

            } else {
                Console.Out.WriteLine("Buscando usuarios:");

                using (StreamWriter sw = File.CreateText(fileName)) {
                    try {
                        DirectoryEntry directoryObject = new DirectoryEntry(ldapEntry);
                        foreach (DirectoryEntry child in directoryObject.Children) {
                            string displayName = GetProperty(child, "displayName");
                            string distinguishedName = GetProperty(child, "distinguishedName");
                            string samAccountName = GetProperty(child, "samAccountName");
                            child.Close();
                            child.Dispose();
                            sw.WriteLine($"{displayName}#{samAccountName}#{distinguishedName}");
                            cantUsuarios++;
                        }
                        directoryObject.Close();
                        directoryObject.Dispose();
                    } catch (DirectoryServicesCOMException ex) {
                        Console.Error.WriteLine("Error: " + ex.Message.ToString());
                    }
                }
                Console.Out.WriteLine(cantUsuarios.ToString() + " usuarios encontrados, fichero generado: " + fileName);
            }
        }

        public static string GetProperty(DirectoryEntry de, string PropertyName) {
            if (de.Properties.Contains(PropertyName)) {
                return de.Properties[PropertyName][0].ToString();
            } else {
                return string.Empty;
            }
        }

        public static bool GetParameters(string[] args, out string ldap, out string fileName) {
            ldap = String.Empty;
            fileName = @"c:\users.txt";
            if (args.Length < 1) {
                return false;
            }
            ldap = args[0];
            if (args.Length >= 2) {
                fileName = args[1];
            }
            return true;
        }
    }
}

30/3/17

Disposición típica en HTML con etiquetas semánticas.

Está sacado de:
https://www.w3.org/TR/css-flexbox-1/



<!DOCTYPE html>
<header>...</header>
<main>
   <article>...</article>
   <nav>...</nav>
   <aside>...</aside>
</main>
<footer>...</footer>

3/2/17

Ordenar tablas de una base de datos para que las referenciadas estén antes de las que referencian

public void OrdenaTablas() {
    List listaOrdenada = new List();
    while (this.lTable.Count > 0) {//mientras haya elementos
        ColocaTablaEnOrden(this.lTable, this.lTable[0], listaOrdenada);
    }
    foreach (var item in listaOrdenada) {
        lTable.Add(item);
    }
}
private void ColocaTablaEnOrden(List listaOriginal, CTableM cTableM, List listaOrdenada) {
    listaOriginal.Remove(cTableM);
    foreach (CRelationM relacion in cTableM.lRelation) {
        string NombreTablaConLaQueSeRelaciona = relacion.tableDestination;
        CTableM tablaRelacionada = listaOriginal.Find(x => x.Name.Equals(NombreTablaConLaQueSeRelaciona));
        if (tablaRelacionada != null) {//Si la tabla relacionada aún está en la lista de tablas a ordenar
            //Meter antes en la lista de ordenadas
            ColocaTablaEnOrden(listaOriginal, tablaRelacionada, listaOrdenada);
        }
    }
    listaOrdenada.Add(cTableM);
}

14/9/16

Crear servicio en Windows:

1 - Nuevo proyecto de tipo: Installed → Visual C# → Classic Desktop → Windows Service.
2 - Saca un editor en donde poner componentes pero lo más importante es poner la propiedad (F4) “ServiceName”. Esta propiedad será el nombre que tiene el servicio en Windows. No será el nombre del ejecutable.
3 - Añadir un “Instalador” se hace con “Add Instaler” en la parte baja de la pestaña de propiedades. No sé exáctamente para qué sirve, pero ahí podremos poner una descripción del servicio y algunas propiedades interesantes más, pero si no se añade esto, luego no se “Instala” el servicio.
4 - “Instalar el Servicio”. No se puede ejecutar directamente, hay que instalarlo y luego iniciarlo. Para instalarlo hay que ejecutar: InstallUtil con el nombre del fichero ejecutable.
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe .\PCSService.exe

5 - “Arrancar el Servicio”. Se hace con net start y el nombre del servicio que hemos puesto en el paso 2.
net start XviConSl

Nota final:
Si en las propiedades del Servicio hemos puesto "AutoLog" a true (que viene por defecto) podremos ver con el visor de eventos (ejecutar "eventvwr" en cmd) mensajes del servicio al instalarse, iniciar, parar tanto en la parte de "sistema" como en la de "aplicaciones".

 

24/8/16

Html y css. Esqueleto página centrada horizontalmente

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml">
 <head> 
  <style> 
   div.clBloqueEncabezado{ 
                  background-color: cyan; 
    text-align: center; 
   } 
   div.clEncabezado{
    display:inline-block;
    background-color:green; 
    padding:0.5em; 
   } 
   div.clCuerpo { 
    text-align: center; 
   } 
   div.clMenu { 
    display: inline-block; 
    background-color: lightblue; 
   } 
   div.clPanelPrincipal { 
    display: inline-block; 
    background-color: lightcoral; 
   } 
   div.clBloquePie { 
    background-color: aquamarine; 
    text-align: center; 
   } 
   div.clPie{ 
    display:inline-block; 
    background-color:green; 
    padding:0.5em; 
   } 
  </style> 
 </head> 
 <body> 
  <div class="clBloqueEncabezado"> 
   <div class="clEncabezado"> 
    Encabezado 
   </div>
  </div> 
  <div class="clCuerpo"> 
   <div class="clMenu"> 
    <h2>Menú</h2> 
    <ul> 
     <li>Uno</li> 
     <li>Dos</li> 
     <li>Tres</li> 
    </ul> 
   </div> 
   <div class="clPanelPrincipal">panelPrincipal</div> 
  </div> 
  <div class="clBloquePie">
   <div class="clPie">Pie</div> 
  </div> 
 </body> 
</html>

19/8/16

Buscar con grep

grep -l -r -i --include="*.cs" "tExto a buscar" .
(Ojo que hay un punto al final)
  • -l que muestre solo el nombre
  • -r que busque en los directorios recursivamente.
  • -i CaseInsensitive. Que no distinga mayúsculas de minúsculas.
  • --include="*.cs". Tipos de fichero a buscar.
  • El punto al final es "Donde" buscar. En este caso en el directorio actual.

    (Si no se pone da un error extraño)

    grep: (entrada estándar): Not enough space

Para windows se consigue aquí


29/6/16

Hola mundo con C# Interactive de Visual Studio 2015

> #r "System.Windows.Forms" //Cargar el ensamblado
> using System.Windows.Forms; //Usar el Namespace
> MessageBox.Show("Hola"); //Mostrar el mensaje

9/6/16

Incluir fichero css en código con JSF.

Definiendo en el código xhtml la etiqueta h con
xmlns:h="http://java.sun.com/jsf/html"

Escribimos:

<h:outputStylesheet library="css" name="Estilos.css"  />

En cualquier parte del código

Lo que genera incluye en la cabecera, y con la ruta adecuada, y ... con parámetros que no entiendo un enlace
<link type="text/css" rel="stylesheet"
href="/proyecto/javax.faces.resource/Estilos.css.xhtml?ln=css" />
Pero el caso es que funciona. Si se usa algún estilo en la página lo usa.
Ejemplo:
<p:panelGrid columns="2" columnClasses="alinearArriba">

20/4/16

Conectar Java con SqlServer.

  1. Abrir SqlServer para conexión por tcp/ip
  2. Para SqlServer 2008 sería:

    Ejecutar: Microsoft SQL Server 2008>Herramientas de configuración>Administración de Configuración de SQL Server

    Desplegar "Configuración de red de SQL Server", "Protocolos de " [Nombre instancia], y en TCP/IP dejar como habilitado

  3. Conseguir el jar adecuado.
  4. página de Microsoft sobre el tema

    Para la Java 1.7 corresponde el sqljdbc41.jar que habría que bajar de Internet

  5. La cadena de conexión
  6. Aquí está la madre del cordero.

    En mi caso "jdbc:sqlserver:" es siempre fijo.

    //nombre servidor:numero de puerto

    instanceName=nombre de instancia(si hay varias en el mismo equipo es fundamental ponerla)

    si se trabaja con autenticación de sqlServer (no Directorio Activo), user y password

    En resumen:

    "jdbc:sqlserver://localhost:1433;instanceName=SQLEXPRESS2008;databaseName=nombreBD;user=sa;password=secreta";

Con esto funciono.

Añado código de ejemplo:(Sacado de uno de los ejemplos de Microsoft que vienen junto al .jar para conectarse)


import java.sql.*;


public class CrudSqlServer1 {

 public static void main(String[] args) {
  // Create a variable for the connection string.
  String connectionUrl = "jdbc:sqlserver://localhost:1433;instanceName=SQLEXPRESS2008;databaseName=nombreBD;user=sa;password=secreta";

  // Declare the JDBC objects.
  Connection con = null;
  Statement stmt = null;
  ResultSet rs = null;
  
         try {
          // Establish the connection.
          Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
              con = DriverManager.getConnection(connectionUrl);
            
              // Create and execute an SQL statement that returns some data.
              String SQL = "SELECT * FROM Tabla1";
              stmt = con.createStatement();
              rs = stmt.executeQuery(SQL);
            
              // Iterate through the data in the result set and display it.
              while (rs.next()) {
               System.out.println(rs.getString(4) + " " + rs.getString(6));
              }
              System.out.println("FIN");
         }
        
  // Handle any errors that may have occurred.
  catch (Exception e) {
   e.printStackTrace();
  }

  finally {
   if (rs != null) try { rs.close(); } catch(Exception e) {}
       if (stmt != null) try { stmt.close(); } catch(Exception e) {}
       if (con != null) try { con.close(); } catch(Exception e) {}
  }

 }

}

19/3/16

Vim. Fijar los espacios de un tab. 8 es mucho.

Hay que poner las dos variables.
:set ts=4
:set sw=4
Siempre el mismo número. Es para el tab y el >>. que por lo visto, no son lo mismo.