Last active
February 3, 2017 09:41
-
-
Save dinigo/066eb7fc053d9fd48be1e9a1b932121c to your computer and use it in GitHub Desktop.
Script para calcular altas y bajas para el DMP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env Rscript | |
args = commandArgs(trailingOnly=TRUE) | |
base_file <- paste0(getwd(),'/',args[1]) | |
delta_file <- paste0(getwd(),'/',args[2]) | |
altas_file <- paste0(getwd(),'/',args[3]) | |
bajas_file <- paste0(getwd(),'/',args[4]) | |
cat('cargando base... \n'); | |
base <- read.csv(base_file,sep=',',header=FALSE) | |
base <- t(base) | |
cat('cargando delta... \n'); | |
delta <- read.csv(delta_file,sep=',',header=FALSE) | |
delta <- t(delta) | |
cat('calculando bajas... \n') | |
bajas <- base[!base%in%delta] | |
cat('calculando altas.. \n') | |
altas <- delta[!delta%in%base] | |
cat('escribiendo bajas... \n'); | |
write.csv(altas, file = altas_file,row.names=FALSE,quote=FALSE) | |
cat('escribiendo altas... \n'); | |
write.csv(bajas, file = bajas_file,row.names=FALSE,quote=FALSE) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# setopt shwordsplit | |
# Script para calcular las altas y bajas en cada mes entre dos archivos | |
#===================================================================# | |
# # | |
# Define las varaibles y flags necesarios para almacenar la # | |
# configuracion del programa # | |
# # | |
#===================================================================# | |
# Flags | |
VERBOSE=true # flag de verbose | |
CLEAN=true # flag para limpiar los archivos cuando acaba el script | |
LOWER=false # flag para lowercase | |
COMPRESS=false # flag para comprimir | |
UPLOAD=false # flag para subir los archivos tras transformarlos | |
HASH=false # flag para calcular el hash de los ids | |
BAD_PARAMS=false # flag para mostrar la ayuda despues de parsear los params | |
DEBUG=false # flag para mostrar información de debug | |
# Archivos | |
BASE="" # archivo base sobre el que se aplican incrementos | |
DELTA="" # archivo incremental | |
OUTPUT="" # nombre del archivo de salida (opcioneal) | |
LOG_FILE=log.html # archivo de log por defecto | |
# Config | |
SCRIPT_NAME="$0" # nombre del script | |
ARGS="$@" # todos los argumentos con que se llamo al script | |
TRAITS="" # array de traits que añadir a las altas | |
EXECUTE="" # array de traits para ejecutar | |
REMOVE_TRAITS=() # array de id de traits que eliminar de las bajas | |
TEMP_FILES="" # lista de archivos temporales genrados por el script | |
COMMAND="" # comando que pasar al programa de encriptacion | |
ROW="" # columna en que se encuentra el id a encruptar | |
SECONDS=$(date +%s) # fecha en segundos en que se comenzó a ejecutar el script | |
PARAMS=$# # numero de parametros con que se invoco el script | |
GIST_URL="https://api.github.com/gists/066eb7fc053d9fd48be1e9a1b932121c" | |
DEPENDENCIES="coreutils r jq wget curl" # dependencias de la aplicacion | |
# Analitica | |
TRACKING_ID="UA-69106054-6" # propiedad de google analytics | |
APP_VERSION="12" # version de la app, tambien se usa para update | |
APP_NAME="DMP Upload" # nombre de la app | |
APP_ID="dmp-upload:shell" # nombre descriptivo de la app | |
APP_PATH="" # variable acumulador path para el estado actual | |
# Alias | |
# Si estamos en mac usamos gdate en lugar de date | |
if [[ $(uname) -eq 'Darwin' ]]; then | |
date () { gdate "$@"; } | |
fi | |
#===================================================================# | |
# # | |
# Define las functiones y demas utilidades que se usaran durante # | |
# la ejecucion del programa. Siempre manteniendo la filosofia # | |
# kiss y burrito code # | |
# # | |
#===================================================================# | |
# Elimina todos los archivos en la lista de temporales | |
cleanup(){ | |
if [[ $CLEAN ]]; then | |
for file in $TEMP_FILES; do | |
[ -f $file ] && rm $file | |
done | |
fi | |
} | |
# Comprueba que se cumplen las dependencias del programa y las instala | |
check_dependencies(){ | |
print dark_gray "Comprobando dependencias" | |
if [[ ! -f $LOG_FILE ]]; then | |
print dark_gray "Descargando plantilla de log" | |
local gist=$(curl -s $GIST_URL) | |
local log_url=$(echo $gist | jq -r '.files.log_template.raw_url') | |
curl -s -o $LOG_FILE $log_url | |
fi | |
if [[ ! -f difference ]]; then | |
print dark_gray "Descargando script para cruzar altas y bajas" | |
local gist=$(curl -s $GIST_URL) | |
local dif_url=$(echo $gist | jq -r '.files.difference.raw_url') | |
curl -s -o difference $dif_url | |
chmod +x difference | |
fi | |
if ! command -v brew >/dev/null 2>&1; then | |
print grey "---------------------------" | |
print white " Instalando gestor de paquetes" | |
event "install" "start" "dependency" "brew" | |
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" | |
event "install" "finished" "dependency" "brew" | |
else | |
$DEBUG && print grey " Brew instalado" | |
fi | |
for dep in $DEPENDENCIES;do | |
if ! brew list $dep >/dev/null 2>&1; then | |
print white " Instalando dependencia: $dep" | |
event "install" "start" "dependency" "$dep" | |
case $dep in | |
r) | |
brew tap homebrew/science | |
brew install Caskroom/cask/xquartz | |
;; | |
coreutils) | |
brew tap homebrew/dupes | |
;; | |
esac | |
brew install $dep --with-default-names | |
event "install" "finished" "dependency" "$dep" | |
else | |
$DEBUG && print grey " Dependencia satisfecha: $dep" | |
fi | |
done | |
} | |
# Muestra una animación y el tiempo que lleva ejecutándose el último proceso | |
spinner(){ | |
local pid=$1 | |
local delay=0.1 | |
local start_time=$(date +%s) | |
local end_time='' | |
local seconds='' | |
local elapsed='' | |
while [ $(ps -eo pid | grep $pid) ]; do | |
end_time=$(date +%s) | |
seconds=$(($end_time - $start_time)) | |
elapsed=$(date -u -d @${seconds} +"%T") | |
for i in \| / - \\; do | |
printf ' procesando %s [%c]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b' $elapsed $i | |
sleep $delay | |
done | |
done | |
printf '\b\b\b\b \n' | |
} | |
# Comprueba si hay aactualizaciones, las descarga y actualiza | |
check_upgrade(){ | |
event "function" "run" "check_upgrade" | |
log dark_gray "Comprobando actualizaciones" | |
local gist=$(curl -s $GIST_URL) | |
local latest=$(echo $gist | jq -r '.files.version.content') | |
local script_url=$(echo $gist | jq -r '.files.dmp_upload.raw_url') | |
local log_url=$(echo $gist | jq -r '.files.log_template.raw_url') | |
local difference_url=$(echo $gist | jq -r '.files.difference.raw_url') | |
if [[ $latest -gt $APP_VERSION ]]; then | |
event "update" "start" "script" "$latest" | |
log green "Actualizando de la version $APP_VERSION a la $latest" | |
curl -s -o dmp_upload $script_url | |
mv $LOG_FILE back_$LOG_FILE | |
curl -s -o $LOG_FILE $log_url | |
event "update" "finished" "script" "$latest" | |
log green "Ejecutando la nueva version" | |
chmod +x dmp_upload | |
./dmp_upload $ARGS | |
exit 0 | |
fi | |
} | |
# Procesa el mensaje a loguear | |
log(){ | |
local code=$1 | |
local message=$2 | |
case $code in | |
error) | |
event "function" "error" "log" "$message" | |
print red "$message";; | |
error) | |
event "function" "warning" "log" "$message" | |
print orange "$message";; | |
open) | |
event "function" "open" "log" | |
open_log;; | |
*) | |
append_log $code "$message" | |
$VERBOSE && print $code "$message" | |
;; | |
esac | |
} | |
# Crea los tags necesarios para el log | |
open_log(){ | |
event "function" "run" "open_log" | |
# agrega el indice | |
local title="$(date +"%y-%m-%d %H:%M")" | |
local id=entry-$SECONDS | |
local entry="<li><a href=\"#$id\">$title</a></li>" | |
local entry_tag="ul" | |
local pre="<pre id=\"$id\"><span>$title</span></pre>" | |
local pre_tag="body div div" | |
append_html "$entry" "$entry_tag" | |
append_html "$pre" "$pre_tag" | |
} | |
# Agrega un log | |
append_log(){ | |
local color=$1 | |
local message=$2 | |
local text="<span style=\"color:$color\">$message</span>" | |
local selector="div div pre" | |
append_html "$text" "$selector" | |
} | |
# Agrega texto al html justo al final de cierta etiqueta | |
append_html(){ | |
local content=$1 | |
local tags=$2 | |
local closer="" | |
for tag in $tags;do | |
closer="</$tag>\s*$closer" | |
done | |
content="${content//$'\n'/\\n}" #sustituye nuevas lineas por el caracter | |
sed -r -i -e "s|(\s*)($closer)|\n\1$content\1\2|g" $LOG_FILE | |
} | |
# Imprime por terminal el mensaje desseado a color | |
print(){ | |
# extrae los parametros | |
local color=$1 | |
local message="$2" | |
# tabla de colores | |
local blue="\033[0;34m" | |
local red="\033[0;31m" | |
local error="\033[0;31m" | |
local light_red="\033[1;31m" | |
local white="\033[1;37m" | |
local black="\033[0;30m" | |
local dark_gray="\033[1;30m" | |
local green="\033[0;32m" | |
local light_green="\033[1;32m" | |
local orange="\033[0;33m" | |
local warning="\033[0;33m" | |
local yellow="\033[1;33m" | |
local light_blue="\033[1;34m" | |
local purple="\033[0;35m" | |
local light_purple="\033[1;35m" | |
local cyan="\033[0;36m" | |
local light_cyan="\033[1;36m" | |
local grey="\033[0;37m" | |
local COLOR=${!color} | |
echo -e "\033[${COLOR}${message}\033[0m" | |
} | |
# Pregunta si los datos son correctos para continuar el programa | |
ask(){ | |
event "function" "run" "ask" "$message" | |
while true; do | |
echo "Son correctos estos datos? (s|n):" | |
read yn | |
case $yn in | |
[Ss]* ) break;; | |
[Nn]* ) exit 0;; | |
* ) echo "Contesta con 's' o 'n'.";; | |
esac | |
done | |
} | |
# Imprime la ayuda del programa | |
help(){ | |
event "function" "run" "help" | |
echo "./prepare-dmp.sh [argumentos]" | |
echo " -a, --datasource: id del datasource a usar en el archivo de salida" | |
echo " -b, --base: ruta al archivo base" | |
echo " -c, --compress: comprime el archivo de salida" | |
echo " -d, --delta: ruta al archivo incremental" | |
echo " -e, --encrypt: encripta los id\'s" | |
echo " -h, --help: imprime esta ayuda" | |
echo " -k, --keep: mantiene los archivos temporales" | |
echo " -l, --lower: pasa el archivo de salida a minuscula" | |
echo " -o, --output: (opcional) nombre del archivo de salida" | |
echo " -t, --trait traits que actualizar (agregar en altas, elimiar en bajas)" | |
echo " -u, --upload: sube los archivos al ftp" | |
echo " -v, --verbose: activa el modo verbose" | |
echo " -w, --row: fila en que se encuentra el msisdn" | |
echo " -x, --execute: cadena a enviar para hacer match" | |
echo " -m, --md5: calcula el hash md5 de los IDs" | |
echo " -u, --debug: modo debug" | |
echo "" | |
echo " Ejemplo de uso:" | |
echo " $./prepare-upload.sh \\" | |
echo " --verbose \\" | |
echo " --encrypt \\" | |
echo " --compress \\" | |
echo " --lower \\" | |
echo " --base test-base.csv \\" | |
echo " --delta test-deelta.dat \\" | |
echo " --trait 1234 --trait 4321 \\" | |
echo " --execute '\"my_trait\"=\"yes\"'" | |
} | |
# Almacena y obtiene un id a modo de cookie | |
get_uuid() { | |
local client_id_file=${1:-$HOME/.uuid} | |
local client_id="" | |
if [[ -f $client_id_file ]]; then | |
client_id=$(cat $client_id_file) | |
else | |
client_id=$(od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}') | |
echo "$client_id" > $client_id_file | |
fi | |
echo $client_id | |
} | |
# Envia analitica a google | |
analytics() { | |
DOMAIN="www.google-analytics.com" | |
$DEBUG && ANALYTICS_PATH="debug/collect" || ANALYTICS_PATH="collect" | |
PAYLOAD="v=1&cid=$(get_uuid)" | |
while [[ $# > 0 ]] ; do | |
case "$1" in | |
-t|--t|--type) | |
shift | |
PAYLOAD+="&t=$1" | |
;; | |
--tid|--tracking-id) | |
shift | |
PAYLOAD+="&tid=$1" | |
;; | |
--dh|--document-hostname) | |
shift | |
PAYLOAD+="&dh=$1" | |
;; | |
--dp|--document-path) | |
shift | |
PAYLOAD+="&dp=$1" | |
;; | |
--dt|--document-title) | |
shift | |
PAYLOAD+="&dt=$1" | |
;; | |
--ec|--event-category) | |
shift | |
PAYLOAD+="&ec=$1" | |
;; | |
--ea|--event-action) | |
shift | |
PAYLOAD+="&ea=$1" | |
;; | |
--el|--event-label) | |
shift | |
PAYLOAD+="&el=$1" | |
;; | |
--ev|--event-value) | |
shift | |
PAYLOAD+="&ev=$1" | |
;; | |
--av|--app-version) | |
shift | |
PAYLOAD+="&av=$1" | |
;; | |
--aid|--app-id) | |
shift | |
PAYLOAD+="&aid=$1" | |
;; | |
--an|--app-name) | |
shift | |
PAYLOAD+="&an=$1" | |
;; | |
esac | |
shift | |
done | |
URL="https://$DOMAIN/$ANALYTICS_PATH?$PAYLOAD" | |
if $DEBUG; then | |
curl -X POST --data "$PAYLOAD" $URL | |
else | |
curl -s -X POST --data "$PAYLOAD" $URL > /dev/null& | |
fi | |
} | |
# Abstrae la llamada a la vista de pagina | |
pageview(){ | |
local step=$1 | |
APP_PATH+="/$step" | |
analytics \ | |
--type pageview \ | |
--tracking-id $TRACKING_ID \ | |
--document-hostname "dmp-upload" \ | |
--document-path "$APP_PATH" \ | |
--document-title "$step" \ | |
--app-version $APP_VERSION \ | |
--app-name $APP_NAME \ | |
--app-id $APP_ID | |
} | |
# Abstre la llamada a un evento | |
event(){ | |
local command="--t event --tid $TRACKING_ID --an $APP_NAME --av $APP_VERSION --aid $APP_ID" | |
[[ -n $1 ]] && command+=" --ec $1" | |
[[ -n $2 ]] && command+=" --ea $2" | |
[[ -n $3 ]] && command+=" --el $3" | |
[[ -n $4 ]] && command+=" --ev $4" | |
analytics $command | |
} | |
#===================================================================# | |
# # | |
# Bloque de inicialización y configuracion # | |
# # | |
#===================================================================# | |
trap cleanup SIGHUP SIGINT SIGTERM | |
check_dependencies | |
log open | |
pageview "start" | |
check_upgrade | |
VERBOSE=false | |
#===================================================================# | |
# # | |
# Parse a los parametros de entrada para construir la config # | |
# # | |
#===================================================================# | |
# parsea los parametros que se pasan al script | |
while [[ $# > 0 ]] ; do | |
case "$1" in | |
# imprime la ayuda | |
-h|--help) | |
help | |
;; | |
# flag que activa el modo verbose | |
-v|--verbose) | |
VERBOSE=true | |
log dark_gray "Modo verbose" | |
;; | |
# flag para encriptar los ids | |
-e|--encrypt) | |
COMMAND+=" --encrypt" | |
log dark_gray "Encriptar los IDs" | |
;; | |
# flag para calcular el hash de los ids | |
-m|--md5) | |
COMMAND+=" --md5" | |
log dark_gray "Hashear los IDs" | |
;; | |
# nombre del datasource al que pertenecen los traits | |
-a|--datasource) | |
shift | |
OUTPUT=ftp_dpm_$1_$SECONDS.sync | |
log dark_gray "Archivo de salida $OUTPUT" | |
;; | |
# flag para comprimir el archivo al terminar de procesarlo | |
-c|--compress) | |
COMPRESS=true | |
log dark_gray "Comprime el archivo de salida" | |
;; | |
# flag hace que se pasen a minuscula los resultados de encriptar | |
-l|--lower) | |
COMMAND+=" --lowercase" | |
LOWER=true | |
log dark_gray "Convertir a minusculas" | |
;; | |
# aunque parezca confuso este comando toma como id la COLUMNA dada | |
-w|--row) | |
shift | |
log dark_gray "Columna $1" | |
COMMAND+=" --row $1" | |
;; | |
# nombre del archivo base | |
-b|--base) | |
shift | |
BASE=$1 | |
log dark_gray "Archivo base: $BASE" | |
;; | |
# nombre del archivo incremental | |
-d|--delta) | |
shift | |
DELTA=$1 | |
log dark_gray "Archivo incremental: $DELTA" | |
;; | |
# configuracion especial para el programa msisdn | |
-x|--execute) | |
shift | |
EXECUTE+=" $1" | |
log dark_gray "Ejecuta la variable $1" | |
;; | |
# trait que agregar a las altas | |
-t|--trait) | |
shift | |
TRAITS+=" d_sid=$1" | |
REMOVE_TRAITS+=" d_unsid=$1" | |
log dark_gray "Actualizar trait: $1" | |
;; | |
# archivo de salida | |
-o|--output) | |
shift | |
OUTPUT=$1 | |
log dark_gray "Archivo de salida: $1" | |
;; | |
# flag que desactiva la limpieza | |
-k|--keep) | |
CLEAN=false | |
log dark_gray "Muestra informacion del proceso" | |
;; | |
# flag para subir automaticamente el archivo al terminar de procesarlo | |
-u|--upload) | |
UPLOAD=true | |
VERBOSE=true | |
COMPRESS=true # si se va a subir es necesario comprimirlo | |
log dark_gray "Sube los archivos al ftp" | |
;; | |
-u|--debug) | |
DEBUG=true | |
log dark_gray "Modo debug activado" | |
;; | |
esac | |
shift | |
done | |
#===================================================================# | |
# # | |
# Realiza las comprobaciones basadas en los parametros antes de # | |
# iniciar la ejecucion del programa y avisa de posibles errores # | |
# # | |
#===================================================================# | |
# si no se ha podido determinar el nombre de archivo de salida por el datasource o explicito | |
if [ -z $OUTPUT ]; then | |
log error "Debe especificar un archivo de salida por medio de el id del datasource o explicito" | |
BAD_PARAMS=true | |
fi | |
# comprueba que hay un archivo sobre el que operar y que existe | |
if [ -z $BASE ]; then | |
log error "No hay archivo sobre el que operar: $BASE" | |
BAD_PARAMS=true | |
elif [ ! -f $BASE ]; then | |
log error "La ruta especificada no es un archivo: $BASE" | |
BAD_PARAMS=true | |
fi | |
# comprueba que, si hay un archivo delta, existe | |
if [[ -n $DELTA && ! -f $DELTA ]]; then | |
log error "No existe el archivo especificado: $DELTA" | |
BAD_PARAMS=true | |
fi | |
# comprueba que se han pasado parametros al programa | |
if [ $PARAMS -eq 0 ]; then | |
log warning "No se han introucido ningun parametro: $@" | |
BAD_PARAMS=true | |
fi | |
# comprueba que se han configurado bien los parametros ftp si se selecona subida | |
if [[ $UPLOAD && ( -z $FTP_HOME || -z $FTP_USER || -z $FTP_PASS ) ]]; then | |
log error "Se ha seleccionado subida al FTP pero no está configurada" | |
BAD_PARAMS=true | |
fi | |
# imprime la ayuda y termina el programa si ocurrió algún error grave | |
if $BAD_PARAMS; then | |
help | |
exit 1 | |
fi | |
#===================================================================# | |
# # | |
# Ejecuta el programa perse: # | |
# Si solo hay archivo base opera con el # | |
# Si hay archivo delta calcula las altas y bajas # | |
# Procesa altas y bajas # | |
# Pasa a minuscula o no # | |
# Comprime el archivo y limpia # | |
# Sube el archivo al DMP # | |
# # | |
#===================================================================# | |
# Si no hay archivo delta trata el archivo base solamente | |
if [ -z $DELTA ]; then | |
pageview "prepare-single-file" | |
log grey "---------------------------" | |
log white " Encripta el archivo de entrada con los traits" | |
(java -jar msisdn.jar \ | |
$COMMAND \ | |
--input $BASE \ | |
--output $OUTPUT \ | |
$REMOVE_TRAITS \ | |
$TRAITS \ | |
$EXECUTE) & | |
spinner $! | |
log white " Ejemplo de linea encriptada:" | |
log green "$(head -n 4 $OUTPUT)" | |
$UPLOAD && ask | |
else | |
pageview "prepare-multi-file" | |
log grey "---------------------------" | |
#1 Extrae las bajas | |
log white " Extrae altas y bajas" | |
(./difference $BASE $DELTA altas.csv bajas.csv) & | |
spinner $! | |
TEMP_FILES+=" bajas.csv altas.csv" | |
log cyan " Altas: $(cat altas.csv | wc -l), Bajas: $(cat bajas.csv | wc -l)" | |
#2 Encripta las bajas con los id de trait que eliminar | |
pageview "extract-unscribers" | |
log grey "---------------------------" | |
log white " Procesa las bajas con los traits a desabilitar" | |
(java -jar msisdn.jar $COMMAND -o bajas-encrypted.csv -i bajas.csv $REMOVE_TRAITS) & | |
spinner $! | |
pageview "process-unscribers" | |
log white " Ejemplo de bajas encriptadas:" | |
log green "$(head -n 4 bajas-encrypted.csv)" | |
mv bajas-encrypted.csv bajas.csv | |
$UPLOAD && ask | |
#4 Encripta las altas | |
pageview "process-subscribers" | |
log grey "---------------------------" | |
log white " Procesa las altas" | |
(java -jar msisdn.jar $COMMAND -i altas.csv -o altas-encrypted.csv $TRAITS $EXECUTE $EXECUTE) & | |
spinner $! | |
log white " Ejemplo de altas encriptadas:" | |
log green "$(head -n 4 altas-encrypted.csv)" | |
$UPLOAD && ask | |
mv altas-encrypted.csv altas.csv | |
log grey "---------------------------" | |
#6 Concatena los archivos de altas y bajas listos | |
pageview "join-files" | |
log white " Concatena las altas y bajas" | |
cat bajas.csv altas.csv > $OUTPUT | |
log cyan " Archivo de salida: $OUTPUT" | |
log cyan " Total: $(cat $OUTPUT | wc -l)" | |
fi | |
if $LOWER; then | |
pageview "lowercase" | |
log grey "---------------------------" | |
log white " Pasa a minuscula" | |
tr A-Z a-z < $OUTPUT > lower_$OUTPUT | |
mv lower_$OUTPUT $OUTPUT | |
fi | |
if $COMPRESS; then | |
pageview "compress" | |
zip -9 $OUTPUT.zip $OUTPUT | |
TEMP_FILES+=" $OUTPUT" | |
OUTPUT=$OUTPUT.zip | |
fi | |
# Limpia los archivos temporales si esta activado | |
if $CLEAN; then | |
pageview "clean" | |
log grey "---------------------------" | |
log white " Elimina archivos temporales" | |
echo $TEMP_FILES | |
cleanup | |
fi | |
if $UPLOAD; then | |
pageview "upload" | |
log grey "---------------------------" | |
log white " Subida de archivos" | |
log white " Comprueba que las muestras de archivo tienen sentido" | |
ask | |
echo " | |
verbose | |
open $FTP_HOME | |
user $FTP_USER $FTP_PASS | |
put $OUTPUT | |
bye" | ftp -n > ftp_$$.log | |
fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<style> | |
* { | |
font-family: "Arial", Helvetica, sans-serif; | |
} | |
body { | |
margin:0; | |
} | |
pre { | |
padding:4em; | |
margin:1em; | |
padding:1em; | |
background:#444; | |
border-radius: 3px; | |
display: inline-block; | |
margin: 1rem; | |
position: relative; | |
transition: box-shadow 0.3s cubic-bezier(.25,.8,.25,1); | |
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); | |
} | |
pre:hover { | |
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); | |
} | |
pre, pre>span { | |
font-family: "Lucida Console", Monaco, monospace; | |
} | |
pre>span:first-of-type { | |
font-weight: bolder; | |
color: grey; | |
} | |
a { | |
color: #00ACD6; | |
} | |
footer {background: #00ACD6;color:white;} | |
ul { | |
list-style-type: none; | |
padding: 0; | |
} | |
li { | |
margin: 20px; | |
} | |
ul a { | |
text-decoration: none; | |
margin: 10px; | |
padding: 10px; | |
} | |
ul a:hover { | |
background-color: #444; | |
color: white; | |
} | |
#wrapper { | |
width: 100%; | |
background-color: #fff; | |
} | |
#top-nav { | |
position: fixed; | |
left: 0; | |
right: 0; | |
top: 0; | |
height: 5em; | |
width: 100%; | |
text-align: center; | |
background-color: black; | |
color:white; | |
} | |
#side-nav { | |
position: fixed; | |
width: 13em | |
height:100vh; | |
left: 0; | |
top: 5em; | |
overflow: auto; | |
background-color: white; | |
} | |
#content-wrapper { | |
overflow: auto; | |
position: fixed; | |
left: 13em; | |
right: 0; | |
top: 5em; | |
height:100vh; | |
background: #e2e1e0; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="wrapper"> | |
<div id="top-nav"> | |
<h1>Logs del proceso de archivos de CRM</h1> | |
</div> | |
<div id="side-nav"> | |
<ul> | |
<li><a href="#inicio">Inicio</a></li> | |
</ul> | |
</div> | |
<div id="content-wrapper"> | |
<pre id="inicio"><span>Inicio de los logs</span></pre></div></div></body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment