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);
}