Commit 9039bbd1 authored by OSiRiS's avatar OSiRiS
Browse files

@ 01:13 hs - Convierto de RST a ORG algunos artículos.

parent 87e60f04
......@@ -14,7 +14,6 @@ hacer y por si fuera poco, documenté todo el proceso. :-)
Lee la nota completa en:
[[file:visualizando-org-mode-con-gnuplot.org][visualizando
orgmode con gnuplot]]
[[file:visualizando-org-mode-con-gnuplot.org][visualizando orgmode con gnuplot]
......@@ -27,6 +27,6 @@ disponibles a fin de lograr un rápido y efectivo despliegue.
[fn:bmesh] http://www.bogota-mesh.org/
[fn:pagina12] http://www.pagina12.com.ar/diario/suplementos/futuro/13-2546-2011-06-11.html
[fn:espinal] http://espinal.redlibre.co/
[fn:escala] http://osiux.com/la-escala-lo-cambia-todo.txt
[fn:escala] http://osiux.com/la-escala-lo-cambia-todo.org
[fn:BAL] http://buenosaireslibre.org
clear-html:
rm html/*.html*
update:
cd html;rsync -avz * vodka:~/osiux
......@@ -53,9 +53,9 @@
** =docs=
*** GNU/Linux
- [[file:ssh-para-gobernar-el-mundo.org][SSH para gobernar el mundo, aprendiendo a usar SSH]]
- [[file:que-no-se-entere-nadie.org][Que no se entere nadie! Análisis de tráfico de red mediante tcpdump]]
- [[file:automatizando-tareas.org][Automatizando Tareas, manejo de crontab, watch y scripts]]
- [[file:ssh-para-gobernar-el-mundo.org][SSH para gobernar el mundo, aprendiendo a usar SSH]]
- [[file:que-no-se-entere-nadie.org][Que no se entere nadie! Análisis de tráfico de red mediante tcpdump]]
- [[file:automatizando-tareas.org][Automatizando Tareas, manejo de crontab, watch y scripts]]
*** Redes Libres / FreeNetworks
- [[file:flisol-bogota-2012.org][Redes Libres en Flisol Bogotá 2012]]
- [[file:la-escala-lo-cambia-todo.org][La escala lo cambia todo]]
......
#+TITLE: la escala lo cambia todo
#+AUTHOR: Osiris Alejandro Gomez
#+EMAIL: osiux@osiux.com
#+LANGUAGE: es
#+LINK_HOME: index.html
#+INCLUDE: header.org
#+DATE: 2012-05-23
Llevo más de seis años participando del proyecto *BuenosAiresLibre*
también conocido como BAL [fn:BAL] y hemos realizado todo tipo de
acciones para hacer crecer la red, desde la mera difusión de las
ventajas de ser parte de una red libre, autogestionada por sus propios
usuarios hasta la capacitación técnica mediante talleres de construcción
de antenas como también sobre configuración de distintos equipos, sin
olvidar las innumerables presentaciones, charlas y todo el conocimiento
colectivo acumulado en el wiki [fn:wiki] del proyecto disponible para
cualquiera que tenga ganas de leerlo y modificarlo.
*¿Porqué la red no está tal y como la queremos?. ¿Porqué no hay tantos
nodos y enlaces?*. Seguramente hay muchísimas causas posibles!
No pretendo tirar todo el trabajo realizado por cientos de personas a lo
largo de más de 10 años, todo lo contrario, me parece que debemos
focalizar nuestro esfuerzo porque *¡la escala lo cambia todo!* En
cierto sentido creo que todo lo que se hizo en el proyecto estuvo bien,
algunas decisiones tal vez fueron más efectivas que otras pero visto en
general todo sirvió para llegar a donde estamos hoy y no está mal
mantener viva la idea de que *una red abierta y comunitaria es posible de
realizar*, sólo nos falta reducir la escala para ser más efectivos.
Así que el lema *"si en tu barrio no hay un nodo es porque vos no lo
armaste"* lo cambiaría por *"si en tu barrio no hay una red libre, es
momento de crearla y unirla a otras redes libres"*.
Habiendo participado de la creación de nuevas y pequeñas redes libres,
me consta que un grupo reducido de integrantes es más dinámico, con un
sentido de pertenencia muy alto por tratarse de vecinos, que tienen
una necesidad puntual a resolver y es la falta de una red digital de
datos que permita comunicarse en el barrio/pueblo/ciudad y tener
salida al mundo, pero con las características específicas de ese
lugar. Una muestra de esto son las redes QuintanaLibre [fn:QL] y
DeltaLibre [fn:DL] que comparten el mismo diseño [fn:redlibre] por ser
laboratorios del proyecto ArraigoDigital [fn:arraigo], ambas surgieron
por algo muy concreto, cada una tiene un pionero de BAL que necesita
una buena conexión al mundo para realizar su trabajo y esto no era
posible sólo con los ISP y WISP locales, para ello fue necesario
levantar varios enlaces los cuales son aprovechados para todos los
beneficios que brindan las redes libres, instalando muchos servicios
en la red local que están siempre disponibles, aún cuando no hay
conexión al mundo.
Técnicamente siempre hay una manera de conectar una red con otra red,
aunque usen protocolos de enrutamiento muy distintos, hoy LibreVPN
[fn:LVPN] es un proyecto que está uniendo varias redes libres de
Argentina y ya son parte algunas redes de Colombia, es un experimento y
seguramente encontraremos mejores maneras con el tiempo pero no tengo
dudas de que son necesarias redes zonales y me atrevo a decir que en
Buenos Aires sería ideal contar con una red libre por cada barrio,
brindando autonomía barrial para luego interconectar todas las redes
zonales y que sean parte del gran proyecto BAL sin perder identidad.
Creo que en parte este enfoque reduciría las fricciones y contratiempos
que todos conocemos y que son propios de cualquier proyecto y gran
número de personas involucradas, pretender hacer las cosas de una sola
manera y que todos estemos de acuerdo, cuando podemos hacerlas de
diversas formas y luego interconectarnos y cooperar.
No olvidemos el primer punto del *Manifiesto de las Redes Libres*
[fn:manifiesto] *garantizar la descentralización* y el punto seis
*promover la creación de otras redes libres, su interconexión e
interoperabilidad*.
BAL siempre ha fomentado la creación y unión de nuevas redes libres
dentro y fuera del país, es hora de empezar por casa!
[fn:BAL] http://www.buenosaireslibre.org
[fn:wiki] http://wiki.buenosaireslibre.org
[fn:manifiesto] http://redeslibres.org/es/manifiesto-de-las-redes-libres
[fn:QL] http://wiki.arraigodigital.org.ar/RedLibre/QuintanaCamp
[fn:DL] http://wiki.arraigodigital.org.ar/RedLibre/DeltaCamp
[fn:redlibre] http://wiki.arraigodigital.org.ar/RedLibre/Diseño
[fn:arraigo] http://wiki.arraigodigital.org.ar
[fn:LVPN] https://kiwwwi.com.ar/librevpn
#+TITLE: MySQL Bash Vim Tips
#+DATE: 2009/12/01
** Crear Base y Usuario
.. code-block:: mysql
CREATE DATABASE sugar CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE user sugar;
GRANT ALL ON sugar.* TO 'sugar'@'%';
SET PASSWORD FOR 'sugar'@'%'=PASSWORD('sugar');
** UTF8
Definir UTF8 en el cliente
.. code-block:: bash
mysql --default-character-set=utf8
Definir UTF8
.. code-block:: mysql
SET NAMES utf8; SELECT * FROM contacts;
MySQL de Bash
=============
Definir Alias
.. code-block:: bash
set alias sugar = 'mysql --default-character-set=utf8 -u sugar -psugar -B sugar -h localhost '
Ejecutar consulta
.. code-block:: bash
echo "SELECT user_name FROM users WHERE is_admin = 1;" | sugar
Listado de Tablas
.. code-block:: bash
set alias tablas='echo "show tables" | sugar | grep -v Tables_in | sort -u'
Listado Tabla Campo
.. code-block:: bash
set alias tablacampo='echo "show tables" | sugar | grep -v Tables_in | while read t; \
do d=$(echo "desc "$t";" | cct15 | grep -v Field | awk1); \
for c in $d;do echo $t"__"$c;done ;done'
Quitar nombre de campo
.. code-block:: bash
mysql -N
Vaciar todas las tablas que contengan la palabra *calls*
.. code-block:: bash
sugar < $(echo "show tables" | sugar | grep calls | while read t;do echo "TRUNCATE table $t;";done)
MySQL desde Vim
===============
Agregar en `.vimrc`
.. code-block:: vim
command -range=% SUGAR :<line1>,<line2>w !mysql -u sugar -psugar -B sugar -t -v -v -v
Ejecutar todo el archivo
.. code-block:: vim
:SUGAR
Ejecutar la línea actual
.. code-block:: vim
:. SUGAR
Ejecutar un rango de líneas
.. code-block:: vim
:3,8 SUGAR
Ejecutar desde línea actual hasta el final
.. code-block:: vim
:.,$ SUGAR
Usar diccionarios
.. code-block:: vim
:set dictionary=tablas, tablacampo
CTRL-X CTRL-K
Reemplazar Texto
================
Traducir valores
.. code-block:: mysql
SELECT REPLACE(REPLACE(direction,'Inbound','Entrante'),'Outbound','Saliente') AS direccion
FROM calls;
Actualizar registros
.. code-block:: mysql
UPDATE contacts SET last_name = REPLACE(last_name, 'NUNEZ', 'NUÑEZ');
Buscar duplicados
=================
.. code-block:: mysql
SELECT last_name, first_name, COUNT(id) AS total
FROM contacts
GROUP BY first_name, last_name
HAVING total > 1
ORDER BY last_name, first_name;
Agrupar
=======
.. code-block:: mysql
SELECT name,
(
SELECT CASE
WHEN EXTRACT(HOUR FROM date_start) < 12
THEN 'mañana'
ELSE 'tarde'
END
) AS turno,
COUNT(id) as total
FROM calls
GROUP BY name, turno
HAVING total > 500
ORDER BY total DESC;
Cruzando tablas
===============
Explicito mejor que implicito
.. code-block:: mysql
SELECT COUNT(cc.id) AS total
FROM calls_contacts cc
LEFT JOIN contacts co ON co.id = cc.contact_id ;
AND cc.deleted = 0
AND co.deleted = 0
SELECT COUNT(cc.id) AS total
FROM calls_contacts cc, contacts co
WHERE co.deleted = 0
AND co.id = cc.contact_id
AND cc.deleted = 0
Contactos con llamadas
.. code-block:: mysql
SELECT COUNT(cc.id) AS total
FROM calls_contacts cc
LEFT JOIN contacts co ON co.id = cc.contact_id;
Contactos con llamadas entrantes
.. code-block:: mysql
SELECT co.last_name,
co.first_name,
CONVERT_TZ(date_start, '+00:00', '-03:00') as fecha
FROM contacts co
INNER JOIN calls_contacts cc ON (cc.contact_id = co.id AND cc.deleted = 0)
INNER JOIN calls ca ON (ca.id = cc.call_id AND ca.deleted = 0)
WHERE co.deleted = 0
AND last_name IS NOT NULL
LIMIT 20;
Actualizar las llamadas de un contacto
.. code-block:: mysql
UPDATE calls ca, contacts co, calls_contacts cc
SET ca.assigned_user_id = (
SELECT id
FROM users
WHERE user_name = 'osiris'
)
WHERE ca.id = cc.call_id
AND co.id = cc.contact_id
AND co.id = '2a756d50-ae20-0754-a7c7-49beb64cee37';
UPDATE calls ca
INNER JOIN calls_contacts cc ON cc.call_id = ca.id
INNER JOIN contacts co ON co.id = cc.contact_id
SET ca.assigned_user_id = (
SELECT id
FROM users
WHERE user_name = 'osiris'
)
WHERE co. = '2a756d50-ae20-0754-a7c7-49beb64cee37';
Insertar desde otra tabla
=========================
.. code-block:: mysql
DROP TABLE IF EXISTS calls_contacts_today;
CREATE TABLE `calls_contacts_today` (
`id` varchar(36) NOT NULL,
`contact_id` varchar(36) NOT NULL,
`call_id` varchar(36) NOT NULL,
`status` varchar(25) default NULL,
`direction` varchar(25) default NULL,
PRIMARY KEY (`call_id`)
);
INSERT INTO calls_contacts_today
(id, contact_id, call_id, status, direction)
SELECT UUID(), cc.contact_id, ca.id, ca.status, ca.direction
FROM calls ca
INNER JOIN calls_contacts cc ON cc.call_id = ca.id
WHERE DATE(ca.date_start) = CURDATE();
AUTOCOMPLETE
============
.. code-block:: mysql
\#
SELECT FROM t<Presionar TAB>
COUNT
=====
.. code-block:: mysql
UPDATE calls set deleted = 1 WHERE status = 'Not Held';
SELECT COUNT(*) FROM calls;
SELECT COUNT(id) FROM calls;
SELECT COUNT(id) FROM calls WHERE deleted = 0;
SELECT SQL_CALC_FOUND_ROWS id FROM calls WHERE deleted = 0 LIMIT 1; SELECT FOUND_ROWS();
EXPLAIN
=======
.. code-block:: mysql
EXPLAIN SELECT COUNT(id)
FROM calls
WHERE deleted = 0
AND assigned_user_id = 'ba8630eb-7442-73f9-a88e-49b6be5882c2';
INDEX
=====
.. code-block:: mysql
SHOW INDEX IN calls;
ALTER TABLE calls ADD INDEX idx_deleted_user (deleted, assigned_user_id);
ALTER TABLE calls DROP INDEX idx_deleted_user;
UNIQUE
======
.. code-block:: mysql
ALTER TABLE calls_contacts_today ADD UNIQUE idx_contact_call (contact_id, call_id);
AUTO_INCREMENT
==============
.. code-block:: mysql
ALTER TABLE tracker AUTO_INCREMENT = 9;
ALTER TABLE tracker MODIFY id INT(11) AUTO_INCREMENT;
REGEXP
======
.. code-block:: mysql
UPDATE contacts
SET postal = SUBSTR(postal,4,7)
WHERE postal NOT REGEXP '^[0-9]{4}$'
AND postal REGEXP '^[A-Z]{3}[0-9]{4}$'
#+TITLE: visualizando dos años de orgmode con gnuplot - viewing two years of orgmode with gnuplot
#+AUTHOR: Osiris Alejandro Gomez
#+EMAIL: osiux@osiux.com
#+LANGUAGE: es
#+LINK_HOME: index.html
#+INCLUDE: header.org
#+DATE: 2011-12-29
** Introducción
Desde que comencé a usar org-mode [#orgmode]_ siempre tuve ganas de
graficar el registro de horas que llevo a diario, pasaron dos largos
años y hoy lo conseguí, luego de 9 horas y 59 minutos:
#+BEGIN_EXAMPLE
** tareas por día.........................................** 9:59
:LOGBOOK:
CLOCK: [2011-12-29 jue 00:04]--[2011-12-29 jue 02:45] => 2:41
CLOCK: [2011-12-28 mié 11:50]--[2011-12-28 mié 13:27] => 1:37
CLOCK: [2011-12-26 lun 16:50]--[2011-12-26 lun 19:00] => 2:10
CLOCK: [2011-12-16 vie 10:24]--[2011-12-16 vie 13:55] => 3:31
:END:
#+END_EXAMPLE
Entonces quiero compartir el proceso de esta mini aventura,
especialmente para todos aquellos que no conocen nada acerca de
org-mode y tienen ganas de saber qué es y par qué sirve.
Es difícil de sintetizar, lo podés usar como anotador, también como
agenda, llevar el registro de horas de un proyecto (o varios), hacer
planillas de cáculo y hasta ejecutar código de distintos lenguajes de
programación entre muchas otras cosas interesantes, casi todo se puede
hacer en org-mode.
Lo interesante es que el formato de archivos usados por orgmode son
simples archivos de texto plano, con esto está garantizada la
compatibiliad y portabilidad de todos tus datos, los podés leer desde
cualquier sistema operativo y con cualquier editor de texto,
obviamente la edición se agiliza muchísimo usando org-mode.
Un detalle, org-mode es parte de Emacs [fn:emacs], pero no hay que
tener miedo, lleva un poco de tiempo aprenderlo y vale la pena.
** Cronometrar Tareas
Para iniciar el reloj de una tarea basta con presionar =C-c C-x C-i=,
es decir =Ctrl+C Ctrl+x Ctrl+i= sobre una tarea, y qué es una tarea,
básicamente una línea que comience con asteriscos:
#+BEGIN_EXAMPLE
* tareas
** primer tarea
** segunda tarea
#+END_EXAMPLE
Se pueden definir atajos de teclado en el archivo =.emacs=, en mi
caso alcanza con presionar =f9 i= para comenzar y luego =f9 o=
para finalizar:
#+BEGIN_SRC emacs-lisp
(global-set-key (kbd "<f9> i") 'org-clock-in)
(global-set-key (kbd "<f9> j") 'org-clock-jump-to-current-clock)
(global-set-key (kbd "<f9> o") 'org-clock-out)
#+END_SRC
Cada vez que se utiliza el reloj se crea una línea que indica la fecha
y hora de comienzo y fin de la tarea y luego la cuenta de las horas y
minutos transcurridos en ese periódo de tiempo:
#+BEGIN_SRC org
CLOCK: [2011-12-29 jue 00:04]--[2011-12-29 jue 02:45] => 2:41
#+END_SRC
Como se trata solamente de texto, es posible editar el texto
manualmente, lo cual permite mucha flexibilidad, sólo hay que respetar
el formato y cada vez que se presione =C-c C-c= sobre la línea, la
cantidad de horas se recalcula. Además se pueden usar las flechas para
avanzar/retrocer días y horas respetando el calendario.
Eso es todo, solo hay que acordarse de iniciar y detener el reloj cada
vez que se está trabajando en una tarea en particular, aunque se puede
registar más tarde editando los valores manualmente.
Sugiero agregar un par de líneas al =.bashrc= que ayudan mucho para
determinar qué estuve haciendo y exáctamente cuándo:
#+BEGIN_SRC sh
export HISTSIZE=100000
export HISTFILESIZE=100000
export HISTTIMEFORMAT='%Y-%m-%d %H:%M '
HISTCONTROL=$HISTCONTROL${HISTCONTROL+,}ignoredups
HISTCONTROL=ignoreboth
shopt -s histappend
#+END_SRC
Esto cambia la vista del comando =history= y es de gran ayuda:
#+BEGIN_SRC sh
> history | tail
5237 2011-12-29 03:05 cdb
5240 2011-12-29 03:16 cd
5241 2011-12-29 03:16 g f9 .emacs
5242 2011-12-29 03:21 :q
5243 2011-12-29 03:29 cd
5245 2011-12-29 03:29 gi hist .bashrc
5246 2011-12-29 03:29 history | tail
#+END_SRC
** Recolectando datos
La idea es recoletar todos los períodos de tiempo utilizados para cada
proyecto (un archivo con extesion =.org=) ordenados por día y
horario en un determinado año y mes.
Para esta tarea realizo un *script bash* el cual lo escribo, edito y
ejecuto directamente desde org-mode usando org-babel [fn:org-babel] .
*** listado de días
Primero busco las líneas que tengan =CLOCK:= seguido de cualquier cosa
=(.*)= para luego buscar el año y mes actual =2011-12= seguido de un
número de dos cifras =[0-9]{2}= en todos los archivos =*.org=, usando
el comando =egrep=:
#+BEGIN_SRC sh :export code
egrep -ho "CLOCK:(.*)2011-12-[0-9]{2}" *.org
#+END_SRC
y obtengo muchas líneas como éstas:
#+BEGIN_EXAMPLE
...
CLOCK: [2011-12-26 lun 11:19]--[2011-12-26
CLOCK: [2011-12-21 mié 11:31]--[2011-12-21
CLOCK: [2011-12-19 lun 14:18]--[2011-12-19
CLOCK: [2011-12-12 lun 10:04]--[2011-12-12
CLOCK: [2011-12-16 vie 01:22]--[2011-12-16
CLOCK: [2011-12-16 vie 01:17]--[2011-12-16
...
#+END_EXAMPLE
a continuación me quedo sólo con =AÑO-MES-DIA=:
#+BEGIN_SRC sh :export code
egrep -ho "CLOCK:(.*)2011-12-[0-9]{2}" *.org | \
awk '{print $2}' | tr -d "[" | sort -u
#+END_SRC
elimino los caracteres `[` y ordeno la lista dejando valores únicos:
#+BEGIN_EXAMPLE
2011-12-12
2011-12-16
2011-12-19
2011-12-21
2011-12-26
#+END_EXAMPLE
todo esto para obtener la lista de días en los cuales hay tareas
cronometradas, ya que no siempre estoy registrando horas.
*** listado de archivos
De manera similar al paso anterior hago lo mismo para obtener el
listado de archivos de los proyectos registrados:
#+BEGIN_SRC sh :export code
egrep -l "CLOCK:(.*)2011-12-[0-9]{2}" *.org | sort -u
#+END_SRC
el resultado son nombres de archivos:
#+BEGIN_EXAMPLE
almuerzo.org
auditoria.org
bal.org
caipiroska.org
gcoop.org
malbec.org
org.org
osiux.org
plot.org
#+END_EXAMPLE
*** Armando la matriz
Con el listado de días y archivos estamos en condiciones de completar
una matriz para cada día y proyecto especificando la hora de inicio de
cada tarea y la cantidad de minutos consumidos, siendo usadas las
filas para los días y un par de columnas (inicio y minutos) para cada