Archive for February, 2008

Backing up a mediawiki wiki

Friday, February 22nd, 2008

Have been filling my wiki with lots of things. Since the data is quite important: I cannot afford to loose it, I must arrange some kind of backup scheme for it. I Googled a lot and found many disperse things that, now, I try to put all together in what I think is a complete solution for the problem and quite general and simple.

For this I assume the following:

  1. ftp.server.of.wiki : is the url of the ftp server where your wiki is stored
  2. ftp_username : the username to access ftp.server.of.wiki
  3. ftp_username_password : the password for ftp_username
  4. remote_path_to_wiki : is the path, from the root of your ftp server (the ftp.server.of.wiki), to your wiki
  5. local_path_to_wiki_database_backup : is the path to the local directory where you want to store your wiki database backup
  6. local_path_to_wiki_dir_backup : is the path to the local directory where you want to store you wiki directory backup
  7. wiki_database_name : the name of your wiki database
  8. wiki_database_username : the username you configure to access the wiki database
  9. database_user_password : the password for the user wiki_database_username
  10. wiki.database.server : the url of the database server of you wiki database
  11. database_backup_filename : the name of the file to where you want to save the backup of you database
  12. you are using mysql

Let us do this by steps:

  1. database backup
  2. wiki files backup
  3. automate backup

1- Database backup

To backup the database one just needs to use the command mysqldump. This command is available in windows and in linux, so that you can do this in both systems. Do this by simply typing:

1
mysqldump -uwiki_database_username -hwiki.database.server -pdatabase_user_password wiki_database_name > database_backup_filename.sql

If this ran correctly now you should have a file with the whole SQL commands to restore your database.

2- wiki files backup

To backup you wiki files you have many options, one is to use rsync but that is not possible always, as happened to me, where my host did not allow me to use it. So my option was ftp. I searched on the internet and I found lftp which is better than ftp because it really assures you that the transfer occurred and you can use the mirror command. For this we just need to type:

1
lftp -u ''ftp_username,ftp_username_password" -e "mirror remote_path_to_wiki local_path_to_wiki_dir_backup" ftp.server.of.wiki

This command will copy everything. You could used instead the following command just just copies the new files:

1
lftp -u ''ftp_username,ftp_username_password" -e "mirror --only-newer remote_path_to_wiki local_path_to_wiki_dir_backup" ftp.server.of.wiki

I also got some problems with empty directories, with the v.3.0.6 of lftp. Then installed the latest version, the v.3.6.3 and everything was ok, so make sure you have the last version.

3- Automate backup

Doing this everyime you want to backup is ok, but if you are like me, you forget to do it regularly or you will end up waking in the night thinking: “F#$%k! I haven’t done a backup for 3 weeks…”. So, for this I decided that I must automate the process of backup up. I use cron (or crontab. Let us first set up a file that sets up the cron jobs, that is the commands we want to execute regularly.

I am a python fan so I made a python script that automates both processes I have just described above. I will not explain how it works, just trust that when you run the python script I put next, say it is called wiki_backup.py, by typing python wiki_backup.py it performs the previous operations. So you just need to copy paste this code to a file and name it, wiki_backup.py and put it wherever you want.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#! /usr/bin/python
###############################################################################
#
#   Script that makes the backup of a mediawiki wiki located
#   at a remote host. To do it, it makes a backup of:
#      1- database
#      2- wiki directory
#
#   INPUTS:
#       database_username: username of the wiki backup
#       database_name: name of the wiki database
#       database_username_password: password for the user database_username
#       database_server: the url of the database server that hold the wiki database
#       ftp_server: the url of the ftp server where the wiki is stored
#       ftp_username: the username to access the ftp server where the wiki is stored
#       ftp_password: the password for the ftp_user
#       backup_directory_name: the name of the directory where you want to backup
#                              your wiki. This directory is created in your home dir
#       wiki_name: the name of your wiki, used to create some of the backup files.
#
#   RESULTS:
#      Everytime the script is run, a file named:
#         wiki_name_YYYYMMDD.sql
#      is created, with YYYY the year, MM the month and DD the day.
#      This file will be stored in the subdirectory under backup_directory_name
#      named database_backups.
#
#      Also all the content of the remote dir where your wiki is is stored
#      inside backup_directory_name in a folder named wiki_files_backup.
#      This backup is incremental.
#
###############################################################################
 
###############################################################################
#
# User input data
#
database_username = "insert_here"
database_name = "insert_here"
database_username_password = "insert_here"
database_server = "insert_here"
ftp_server = "insert_here"
ftp_username = "insert_here"
ftp_password = "insert_here"
wiki_remote_dir = "insert_here"
backup_directory_name = "insert_here"
wiki_name = "insert_here"
#
###############################################################################
 
# import the necessary modules
 
# module for running operating system commands
import os
# module to have time operations like, getting the time
import time
 
# create the directory structure where to store all the backup files:
#
# ---- ~/
#         |
#         |__backup_directory_name
#                 |
#                 |__database_backups
#                 |__wiki_files_backup
#
 
# check if backup_directory_name exists, if not, create it
 
# get the home directory.
try:
	#If in WINDOWS USERPROFILE exists
	home_dir = os.environ["USERPROFILE"]
except KeyError:
	# if an error occurs, trap the error and use
	# HOME instead
	home_dir = os.environ["HOME"]
 
# make the root dir for the backups
root_dir_backup = os.path.join(home_dir, backup_directory_name)
 
# check if root_dir_backup exists
if not os.path.exists(root_dir_backup):
	# if it does not exist create it
	os.mkdir(root_dir_backup)
# if exists, check if it is a directory
elif not os.path.isdir(root_dir_backup):
	# if it is not, create it
	os.mkdir(root_dir_backup)
 
# now generate the subdirectories names
database_backups_dir = os.path.join(root_dir_backup, "database_backups")
wiki_files_backup_dir = os.path.join(root_dir_backup, "wiki_files_backup")
 
# check if the directories exist and create them if not, as before
#database_backups_dir
if not os.path.exists(database_backups_dir):
	# if it does not exist create it
	os.mkdir(database_backups_dir)
# if exists, check if it is a directory
elif not os.path.isdir(database_backups_dir):
	# if it is not, create it
	os.mkdir(database_backups_dir)
# wiki_files_backup_dir
if not os.path.exists(wiki_files_backup_dir):
	# if it does not exist create it
	os.mkdir(wiki_files_backup_dir)
# if exists, check if it is a directory
elif not os.path.isdir(wiki_files_backup_dir):
	# if it is not, create it
	os.mkdir(wiki_files_backup_dir)
 
# now that the directory structure is created, generate the
# filename for the database backup, using the current time and the
# wiki name: wiki_name_YYYYMMDD.sql
 
# get the local time
localtime = time.localtime()
database_backup_filename = "%s_%02d%02d%02d.sql" % (wiki_name, localtime[0], localtime[1], localtime[2])
database_backup_filename_complete_path = os.path.join(database_backups_dir, database_backup_filename)
 
# give info to the user
print "making backup of wiki database:"
print "database: %s" % database_name
print "server: %s" % database_server
print "username: %s" % database_username
 
# backup the database from the remote server
command = "mysqldump -u%s -h%s -p%s %s > %s" % (database_username, database_server, database_username_password, database_name, database_backup_filename_complete_path)
os.system(command)
 
# give info to the user
print ""
print "making backup of wiki files:"
print "ftp server: %s" % ftp_server
print "remote dir: %s" % wiki_remote_dir
print "username: %s" % ftp_username
 
# backup the wiki directory from the remote dir
command = "lftp -u \"%s,%s\" -e \"mirror --only-newer %s %s\" %s" % (ftp_username, ftp_password, wiki_remote_dir, wiki_files_backup_dir, ftp_server)
os.system(command)

After, allow that it is executed: doing chmod +x wiki_backup.py on the directory where the file is.

Let us first recall how a cron jobs file is made. Each line of a cron jobs file is a job you want to perform regularly and in that line you specify the regularity and the command to execute, like this:

1
[min] [hour] [day of month] [month] [day of week] [program to be run]

where:

  • [min]: the minutes at which the program should run. 0-59. Do not set as * or the program will be run once a minute.
  • [hour]: the hour at which the program should run. 0-23, * for every hour
  • [day of month]: the day of the month at which the program should run. 1-31, * for every day.
  • [month]: the month at which the program should run. 1-12, * for every month.
  • [day of week]: the day of the week at which the program should run. 0-6 where Sunday=0, Monday=1, …, Saturday=6 and * for every day of the week.
  • [program]: the program to be executed. Include full path information.

An example:

1
0,15,30,45 * * * * /usr/bin/foo

where:
To run the program /usr/bin/foo every 15 minutes on every hour, day of the month, month and day of the week. It will run each 15 minutes for as long as the machine is running.Ok, you get the point. For more than you cron job, just put one job at each line of a cron job file.

Let us continue with our mission.

First create the text file with the cron jobs, say cron.wiki. You can do it with any text editor (gedit, kate, emacs, vim, pico, whatever). This file should contain, if you want the backup procedure to run at 03:00 in the morning, everyday of the month, month and day of the week :

0 3 * * * /absolute/path/to/python/script/wiki_backup.py

Now, on a shell add the cron jobs using crontab:

1
crontab cron.wiki

Check if it was added correctly:

1
crontab -l

If your job appears, then everything is ok and you wiki will be backuped everyday at 03:00, now you can relax!

In the near future I will show how to restore a wiki, from the files we are backing up.

del.icio.us Slashdot Digg Technorati Google StumbleUpon

Babel fish

Tuesday, February 19th, 2008
Naquele tempo toda a humanidade falava uma só língua. (…) E nessa cidade [Babilónia] projectaram levantar um templo com a forma de uma torre altíssima que chegasse até aos céus, qualquer coisa que se tornasse um monumento a si próprios. Isto, disseram, impedirá que nos espalhemos ao acaso pela terra toda. O Senhor desceu para ver a cidade e a torre que estavam a levantar:

Vejamos: se isto é o que eles já são capazes de fazer, sendo um só povo com uma só língua, não haverá limites para tudo o que ousarem fazer. Vamos descer e que a língua deles comece a diferenciar-se noutras línguas, de forma que uns não entendam os outros.

E foi dessa forma que o Senhor os espalhou sobre toda a face da terra, tendo cessado a construção daquela cidade. Por isso ficou a chamar-se Babel , porque foi ali que o Senhor diferenciou a língua dos homens, e espalhou-os por toda a terra.

Génesis 11:1-9 - A Torre de Babel

A Torre de Babel por Pieter Brueghel O Ancião

A acreditar nos mitos, somos levados a crer que a proliferação de línguas é um castigo, seja ele do Nosso Senhor, pai castigador, na Igreja Católica, como castigo pela nossa arrogância de acreditar na nossa capacidade enquanto entidade colectiva. Seja, como castigo de Brahma, um deus Hindu, que dicidiu castigar uma árvore demasiado orgulhosa por também acreditar no Homem:

Aqui cresceu, no centro da Terra a maravilhosa “árvore do mundo”, ou “árvore do conhecimento”. Era tão alta que quase chegava ao céu. Dizia no seu coração: “Repousarei a minha cabeça no céu e espalharei os meus ramos por toda a Terra e reunirei todos os Homens debaixo da minha sombra, protegê-los-ei e impedirei que se separem.” Mas Brahma, para castigar o orgulha da árvore, cortou os seus ramos e lançou-os para dentro da Terra e fez diferenças nas crenças, nas línguas e nos costumes que prevalecem na Terra, dispersando os Homens pela sua superfície.

Seja, segundo os Wa-Sania, um povo Bantu Africano, devido a uma loucura generalizada que surgiu no decorrer de uma severa escassez de alimentos, fazendo com que as pessoas que inicialmente falavam todas uma só língua, vagueassem em todas as direcções, vociferando estranhas palavras, dando origem às diferentes línguas.

Seja por uma disputa de Deuses, segundo a Mitologia Grega, em que Hermes instigou a diversidade das línguas juntamente com a separação das nações, que viviam desde sempre sob o governo de Zeus. Levando Zeus a perder o prazer no governo dos destinos do Homem, entregando-o ao primeiro rei Homem: Foroneus.

Está sempre presente a punição, de alguma forma, e o resultado negativo da incompreensão entre povos.

Estive neste fim de semana a jantar em casa de um amigo meu. Eram cerca de vinte pessoas, seis línguas. Sete, se contarmos com o inglês. Era curioso ver como no meio desta pequena Babilónia, debaixo do calor dos aquecedores que nos protegiam dos sete graus negativos, as conversas faziam-se poliglotamente.

A linguagem já de si é um filtro, entre o que pensamos e o que conseguimos exprimir. Uma linguagem não materna é ainda outro filtro, ainda mais grosseiro. Regredimos aos dezasseis anos, sem possibilidade de brincar com a língua. É o último resquício do castigo divino. Incapaz de impedir a comunicação procura, numa última tentativa, escamotear.

Eu tenho um sonho. Um dia em que cada um possa falar a sua língua materna e que possa ser compreendido por todos. Talvez seja difícil assimilar todas as linguas do mundo num cérebro tão pequeno. Resta-me esperar que encontremos o Babel fish:

The Babel fish is small, yellow and leech-like, and probably the oddest thing in the Universe. It feeds on brainwave energy received not from its own carrier but from those around it. It absorbs all unconscious mental frequencies from this brainwave energy to nourish itself with. It then excretes into the mind of its carrier a telepathic matrix formed by combining the conscious thought frequencies with nerve signals picked up from the speech centres of the brain which has supplied them. The practical upshot of all this is that if you stick a Babel fish in your ear you can instantly understand anything said to you in any form of language.

The Hitchhicker’s Guide to the Galaxy - Douglas Adams

Babel fish diagram

Fica aqui uma brincadeira com a língua:

del.icio.us Slashdot Digg Technorati Google StumbleUpon

 
icon for podpress  Standard Podcast [2:59m]: Play Now | Play in Popup | Download

Xoné Fevereiro 2008

Monday, February 18th, 2008

A Xoné veio cá! Foi a primeira visita que tive.

Toda a gente achou estranho não termos ido a Amesterdão. Sim, não fomos. Ficámos por Delft, Rotertão e Haia. Amesterdão fica para as próximas vezes. Estiveram uns dias maravilhosos, a Ana trouxe o sol. Ficam aqui alguns momentos.


A Xoné a fazer de Niquita.


A Xoné a fazer de xoné.


del.icio.us Slashdot Digg Technorati Google StumbleUpon

A praia em Scheveningen

Monday, February 4th, 2008

Depois de dois posts sensaborões, em inglês e sobre coisas que não interessam a ninguém, vou contar a ida a Scheveningen, em busca da praia.

Depois da azáfama do fim de semana passado, noitada na discoteca, este fim de semana procurámos algo mais calmo. Escolhemos uma ida à praia, em Den Haag: Scheveningen. Já me tinham falado desta praia e também já tinha andado a tentar vê-la pelo Google Maps. Parecia ser uma praia muito comprida com uma largura grande e um areal, aparentemente, branco.

Lá fomos, às 13h00, depois de dormir umas 8 horas, devido à noite agitada no Speakers, o bar/discoteca de Delft, onde estive com o Daniele e o Massimiliano (outro italiano).

Lá fomos, eu e o Daniele, cada um montado na sua bicicleta, armados com luvas, casacos quentes e gorros porque, apesar do sol estar generoso, o frio era cortante.

À saída de Delft ouvimos o som de música, olhámos e reparámos que havia um enorme cortejo. Lembrei-me que era Carnaval. Decidimos ir ver. Quem diria? Os holandeses gostam bastante do carnaval! Era um cortejo de carnaval, enorme, principalmente tendo em conta que Delft é uma cidade pouco maior que Évora. Vimos de tudo, pessoas mais velhas, mais novas, de meia idade, adolescentes, coxos, marrecos, todos metidos no meio do cortejo. Alguns mais produzidos, outros só com um nariz de palhaço. Mas lá íam todos contentes!

Seguimos caminho. O sol põe-se cedo e o nosso destino é a praia.

Pelo caminho o Daniele só dizia:

“Bem, se o sol for assim como hoje mais vezes, acho que me aguento aqui 4 meses…”

“Bem, se a praia tiver boas ondas, acho que me aguento aqui 5 meses…”

“Bem, se conseguirmos ter aulas de surf, e de música, acho que me aguento aqui 6 meses…”

Foi assim a viagem toda, um pouco como a música do “Se um elefante incomoda muita gente, dois elefantes incomodam muito mais… Se dois… “

O que dizer de Den Haag? Não vi muito, mas pareceu-me uma pequena cidade, mais pequena ainda que Roterdão. Talvez com edifícios mais antigos e ruas mais estreitas em alguns locais, mas de resto pareceu-me uma cidade com pouco interesse.

Continuámos direitos à praia. O caminho é muito bonito, saímos do centro de Den Haag e seguimos por uma estrada com árvores de um lado e do outro e uma zona relvada para encobrir os carris do eléctrico que faz a ligação entre Delft - Den Haag - Scheveningen (a praia). Achei uma boa ideia.

Quando chegámos à praia (tenho pena de não ter tirado fotos aos prédios), fiquei com a triste sensação que afinal o Algarve, ou melhor, o atentado arquitectónico que se fez no algarve e um pouco por todos os grandes centros balneares em Portugal, não é algo apenas nosso. Ainda que tenhamos um primeiro ministro com excelentes dotes arquitectónicos. Estava na Holanda mas parecia que estava a passear na marginal de Montegordo, ou de Lagos ou de Sesimbra, com os enormes mamarrachos, ocupados apenas no verão e nos fins-de-semana solarengos, com os restaurantes de praia, com sea food, grilled fish, milk shakes, com as lojas que vendem… o que é que vendem mesmo? Toalhas com tubarões misturados com a bandeira do país, búzios azuis, verdes, amarelos, quadrados, colares, anéis, postais com mulheres e homens saudáveis de mamas e músculos ao léu, roupa interior.

Só me perguntava: “O que é isto?”. Esta cultura pós-moderna é universal. É a globalização…

Perguntei ao Daniele se havia disto em Itália e ele disse: “Sim… Há em todo o lado!”.

Enfim, sempre tínhamos um enorme areal e podíamos ir para lá de olhos fechados e só olhar para o mar. Assim fizémos. Passeámos pelo areal, que era mesmo a perder de vista.

A parte positiva é que o crime arquitectónico não se estendia por uma área gigantesca, estava até muito concentrado em frente ao pontão que avançava para o mar imponente.

Fomos até ao final do pontão, podem ver aqui uma imagem do Google Maps:


View Larger Map

 

Era bastante estranho, como todas as contruções muito perto do mar e ainda mais as que se encontram dentro dele. Parece um pouco uma invasão do Homem num meio que não é o seu. Parece um pouco desgarrado, qual barco encalhado.

Demos ainda mais umas volta pela zona sem prédios e voltámos para casa.

Feitas as contas, pedalámos cerca de 35km e andámos a pé mais uns 10km. Como sou uma flor de estufa, cheguei a casa e não me mexi mais. :-)

Para a galeria completa de imagens, cliquem aqui.

P.S.: A Ana chega amanhã! :-D

del.icio.us Slashdot Digg Technorati Google StumbleUpon

Mounting a remote ssh filesystem using sshfs on Ubuntu

Saturday, February 2nd, 2008

I am working on a Linux computer at the University with a RedHat Entreprise distribution. There I have all my work that:

  1. I wish to have as backuped as possible;
  2. I wish to have easily accessible from my laptop, to upload and download.

I looked for ways to do it and I found sshfs. In this way, as I will show you, whenever I log in to my laptop, with an internet connection available, I have a virtual folder where I have a seamless access to all the files on my pc at the University. This is how I did it:

  1. Enabled the Multiverse on the Synaptics software sources. Went to System–> Administration –> Software sources, then on the Ubuntu software tab, checked the fourth option (Multiverse).
  2. Installed sshfs:
    sudo apt-get install sshfs
  3. Once installed, changed the permissions so that I could mount it as normal user:
    sudo chmod +x /usr/bin/fusermount
  4. Made a mount point directory on my laptop that points to the directory I am mounting on the other machine. In this case I created a directory named lraero19 (which is the name of my computer at the university) on the /media directory:
    sudo mkdir /media/lraero19
  5. Then changed the owner to me:
    sudo chown gorkiana /media/lraero19
  6. Afterwards I had to add my user to the group “fuse” so that I could use it. For that I typed:
    sudo adduser gorkiana fuse

    Then I had to logout and login back again so that the change took effect.

  7. Mounted the remote drive with sshfs. For this I typed in:

    sshfs my_user_name@ip_at_university:/the_directory_to_mount /media/lraero19

  8. To unmount I just type:
    fusermount -u /media/lraero19

Since I have to do this every time I logged in, I decided to automate the process. For that I needed first to get rid of the password prompt. Hence I did this:

  1. I had to create a public key on my laptop and copy it to the university computer so that I did not need to type in the password every time. Typed:
    ssh-keygen -t rsa

    (typed enter to the both question since I do not want a password).

  2. Made a directory named .ssh at my home directory at the university computer:
    mkdir /media/lraero19/.ssh

    (now I can do it as if it was a local directory :-) ).

  3. Then chmoded it:
    chmod 700 /media/lraero19/.ssh
  4. Copied the public key to there:
    cat .ssh/id_rsa.pub >> /media/lraero19/.ssh/authorized_keys
  5. Chmoded it:
    chmod 600 /media/lraero19/.ssh/authorized_keys

Then I wanted it to run everytime I logged in to GNOME, for that I just went to Sytem –> Preferences –> Sessions, then at the startup programs tab just added one more, with the command:

sshfs my_user_name@ip_at_university:/the_directory_to_mount /media/lraero19

Finally I had to get a way of unmounting the drive when I logged out. After many hours googling I found a solution! Edited the file: /etc/gdm/PostSession/Default and added the following line before the exit 0 line:

fusermount -u /media/lraero19

del.icio.us Slashdot Digg Technorati Google StumbleUpon