<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tech</title>
	<atom:link href="http://www.ruyk.com/tech/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.ruyk.com/tech</link>
	<description>Un espacio libre de bugs</description>
	<lastBuildDate>Fri, 06 Apr 2012 14:47:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Converting PostScript files</title>
		<link>http://www.ruyk.com/tech/?p=73</link>
		<comments>http://www.ruyk.com/tech/?p=73#comments</comments>
		<pubDate>Wed, 04 Apr 2012 10:52:16 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=73</guid>
		<description><![CDATA[Converting PostScript (ps) files is necessary sometimes, particularly if you want to produce high quality graphics for LaTeX or you have used the &#8220;print to file&#8221; option of some programs. In Linux, the easiest way to convert this kind of files is to use the convert command, from the ImageMagick package. For example, converting a [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Converting PostScript (ps) files is necessary sometimes, particularly if you want to produce high quality graphics for LaTeX or you have used the &#8220;print to file&#8221; option of some programs.</p>
<p style="text-align: justify;">In Linux, the easiest way to convert this kind of files is to use the convert command, from the<a title="ImageMagick" href="http://www.imagemagick.org/script/index.php" target="_blank"> ImageMagick</a> package. For example, converting a PS file to a JPEG file is as easy as typing this command in the console (assuming you have already installed the aforementioned ImageMagick package):</p>
<pre>convert original.ps destination.jpeg</pre>
<p style="text-align: justify;">Better quality images can be generated using <a title="Ghostscript" href="http://www.gnu.org/software/ghostscript" target="_blank">GhostScript</a> (gs). For example, the same convertion produces (at least for me!) better quality jpeg images:</p>
<pre>gs -q -dNOPAUSE -dBATCH -sDEVICE=jpeg -r300 -sPAPERSIZE=a4  \
      -sOutputFile=destination.jpeg original.ps</pre>
<p style="text-align: justify;">Notice the -sDEVICE parameter, which specify which GV device we want to use and the -r300, which specify the desired resolution (in dpi). -dNOPAUSE and -dBATCH enables the command to be used inside a batch script without requiring user intervention.</p>
<p style="text-align: justify;">They are <a title="Ghostscript device list" href="http://www.gnu.org/software/ghostscript/devices.html" target="_blank">several devices available</a>, some of the most useful for me are:</p>
<ul style="text-align: justify;">
<li>png16m: To convert PS files to PNG</li>
<li>tiff24nc: To produce non-color tiff files, useful to directly print in several devices</li>
<li>epswrite: To generate EPS files</li>
</ul>
<p style="text-align: justify;">Sometimes the original file has excessive blank space. It is possible to use the -dEPScrop  option to remove the margins and try to fit the paper size to the image.</p>
<p style="text-align: justify;">In case the file contains text,  is it possible to further increase quality of the resulting file by using the -dTextAlphaBits=n (where n is 2 or 4) to apply antialiasing to the fonts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=73</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CUDA + Nvidia Optimus in Ubuntu 11.04</title>
		<link>http://www.ruyk.com/tech/?p=68</link>
		<comments>http://www.ruyk.com/tech/?p=68#comments</comments>
		<pubDate>Wed, 31 Aug 2011 17:37:59 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=68</guid>
		<description><![CDATA[Some days ago I bought a new laptop, a Samsung Q330 with an NVIDIA Optimus Card. After installing Ubuntu 11.04, I realized that 3D acceleration and CUDA was not available despite of installing the closed-source NVIDIA kernel driver. Then I realized that NVIDIA Optimus is not fully supported in Linux (my fault for not checking [...]]]></description>
			<content:encoded><![CDATA[<p>Some days ago I bought a new laptop, a Samsung Q330 with an NVIDIA Optimus Card. After installing Ubuntu 11.04, I realized that 3D acceleration and CUDA was not available despite of installing the closed-source NVIDIA kernel driver. Then I realized that NVIDIA Optimus is not fully supported in Linux (my fault for not checking it first!), so I started googling to see if there was some info available. It turns out that an open source project called <em>bumblebee</em> enables the usage of both NVIDIA and Intel IGP card with the proprietary drivers.</p>
<p>Installing <em>bumblebee</em> in Ubuntu 11.04 is easy: just add the ppa</p>
<pre>sudo add-apt-repository ppa:bumblebee/stable</pre>
<p>and then install the bumblebee package</p>
<pre>sudo apt-get update
sudo apt-get install bumblebee</pre>
<p><span style="font-weight: bold;">How it works</span></p>
<p>In addition to the main X screen associated to the first available PTY of your system, bumblebee will create a secondary one, this one with the nvidia driver. Whenever system requires to use this device, the program will be run on the secondary X and the output will be transferred to the main X screen. Bumblebee allows to configure different X transfer methods, being Xv the default (and the one I am using).</p>
<h4>Using CUDA</h4>
<p>As usual, to be able to use CUDA in your system, you need to install the correspondent NVIDIA CUDA driver. Traditionally, I used to install it by hand. However, manual install does not seems to work well with <em>bumblebee</em>. There is a PPA for CUDA available for Ubuntu that worked well for me. Installation instructions are available in<a title="Nvidia CUDA ubuntu way" href="http://samiux.blogspot.com/2011/05/howto-nvidia-cuda-toolkit-40-on-ubuntu.html" target="_blank"> this other blog</a>, although I will put an abstract here for reference pourposes:</p>
<pre><code>sudo add-apt-repository ppa:aaron-haviland/cuda-4.0</code>
<code>sudo apt-get update
sudo apt-get upgrade</code>
<span style="font-family: monospace;">sudo apt-get install nvidia-cuda-gdb nvidia-cuda-toolkit nvidia-compute-profiler libnpp4 nvidia-cuda-doc libcudart4 libcublas4 libcufft4 libcusparse4 libcurand4 nvidia-current nvidia-opencl-dev nvidia-current-dev nvidia-cuda-dev opencl-headers</span>
</pre>
<p>Notice how OpenCL packages are also installed. As stated in the original post blog, additional packages might be required to compile the NVIDIA GPU Computing SDK.</p>
<p>After restarting your gdm, if everything was OK, you will be able to run your CUDA programs. If at first didn&#8217;t work, try using <em>optirun:</em></p>
<pre><em>optirun ./cudaProgram</em></pre>
<p>This will tell <em>bumblebee</em> to force execution of the program in the GPU Device (by using the secondary X server).</p>
<p>I have not tested the OpenGl / CUDA interoperability with this system, although it should work properly. Performance however might be degraded due to the framebuffer transfer.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=68</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Measurement of CUDA programs</title>
		<link>http://www.ruyk.com/tech/?p=61</link>
		<comments>http://www.ruyk.com/tech/?p=61#comments</comments>
		<pubDate>Tue, 10 May 2011 07:45:47 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=61</guid>
		<description><![CDATA[During the last month, while preparing a paper for JP2011, engineers from the SAII (A computer research support unit from University of La Laguna) did interesting research about CUDA benchmarking. Although it might be seen as a trivial task, it required some extra effort. In colaboration with people of our research team (GCAP , High [...]]]></description>
			<content:encoded><![CDATA[<p>During the last month, while preparing a paper for <a title="JP2011" href="http://jp2011.pcg.ull.es/">JP2011</a>, engineers from the <a title="SAII" href="http://www.saii.ull.es/" target="_blank">SAII</a> (A computer research support unit from University of La Laguna) did interesting research about CUDA benchmarking. Although it might be seen as a trivial task, it required some extra effort. In colaboration with people of our research team (<a href="http://blogs.viinv.ull.es/GCAP/" target="_blank">GCAP</a> , High performance computing group of La Laguna University), Iván, one of the engineers involved, has made some interesting notes about this issue in his blog. If you are interested in CUDA, and you need to measure execution times with detailed information, you should take a look into this two articles:</p>
<ul>
<li><a title="Read How to measure time in NVIDA CUDA?" rel="bookmark" href="http://ivanlife.wordpress.com/2011/05/09/time-cuda/">How to measure time in NVIDA CUDA?</a></li>
<li><a title="Read How to make GOOD measurements in NVIDA CUDA?" rel="bookmark" href="http://ivanlife.wordpress.com/2011/05/09/how-to-make-good-measurements-in-nvida-cuda/">How to make GOOD measurements in NVIDA CUDA?</a></li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=61</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HOWTO Profile OpenMP with TAU or OmpP</title>
		<link>http://www.ruyk.com/tech/?p=49</link>
		<comments>http://www.ruyk.com/tech/?p=49#comments</comments>
		<pubDate>Tue, 23 Nov 2010 14:53:12 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=49</guid>
		<description><![CDATA[However, there are some cases where gprof is not enough. In parallel applications, when you have multiple
threads, you want to know which thread is doing what. To get this information, you need a more powerful tool, like TAU.]]></description>
			<content:encoded><![CDATA[<h2 style="text-align: justify;">Introduction</h2>
<p style="text-align: justify;">It&#8217;s been a while since my last post, but I&#8217;ve been working a lot (too much<br />
maybe) recently. As research staff in the TEXT project[0], I am<br />
deeply involved in HPC programming environments.</p>
<p style="text-align: justify;">This post pretends to be a quick help to the (few) people who wants to<br />
instrument OpenMP programs for profiling. We will use TAU and OmpP.</p>
<p style="text-align: justify;"><span id="more-49"></span></p>
<h2 style="text-align: justify;">Brief review of profiling</h2>
<p style="text-align: justify;">Profiling[1] source code requires two phases: First instrumenting the code, and<br />
second, run it to get trace and profile information.  A widely-known profile<br />
tool is GnuProf[2], and its usage is simple. First, compile with the &#8216;-pg&#8217; flag</p>
<p style="text-align: justify;"><code> $ gcc -pg program.c -o program $./program </code></p>
<p style="text-align: justify;">You will notice that the program runs slower, and, when it finished. You will<br />
get a file called gmon.out. Using gprof tool, you can see which function<br />
consumes most time.</p>
<p style="text-align: justify;">This information is useful in simple cases, to identify the time-killer<br />
functions or methods of a code. You can focus on optimizing the most<br />
time-consuming function, because is where you will get the most benefit[3].</p>
<p style="text-align: justify;">However, there are some cases where gprof is not enough. In parallel<br />
applications, when you have multiple threads, you want to know which thread is<br />
doing what. To get this information, you need a more powerful tool.</p>
<h2 style="text-align: justify;">TAU</h2>
<p style="text-align: justify;">TAU[4] is, among other things, an instrumenting tool for timing and<br />
performance. It can instrument MPI code, and produce profile and trace files in<br />
TAU format, which can be converted to several other formats (Vampirtrace,<br />
Slog2, &#8230;)</p>
<h3 style="text-align: justify;">Setup and config</h3>
<p style="text-align: justify;">To use TAU you need to install PDT first (it can be found on [4] also).<br />
Download the source code, and compile it. Don&#8217;t forget to specify the compiler<br />
which you are using (Intel in my case):</p>
<p style="text-align: justify;"><code> $ ./configure -ICPC &amp;&amp; make </code></p>
<p style="text-align: justify;">You will have a directory matching your architecture (x86_64 in my case) where<br />
all the PDT files will be found.</p>
<p style="text-align: justify;">Next step is to build TAU. This is an important step. TAU configure have<br />
several options. As we want to add OpenMP support, we need to specify it at<br />
compile time. There is a graphical tool to do this which I do not recomend.  My<br />
configure line is this one:</p>
<p style="text-align: justify;"><code><br />
$ ./configure -openmp -TRACE -c++=icpc -fortran=intel -cc=icc \<br />
-pdt=/home/username/soft/pdtoolkit-3.16/ -opari -opari_region \<br />
-opari_construct<br />
</code></p>
<p style="text-align: justify;">-openmp enables OpenMP support. -TRACE enables TRACE generation from program<br />
execution (which is NOT generated by default).  Next parameters specify that I<br />
want to use the intel compilers to the instrumentation . Note that, for c, the<br />
Intel compiler is not officially supported, so I specify the compiler name. The<br />
-pdt parameter specifies where the PDT files are found (the ones we built<br />
before). The -opari, -opari_region and -opari_construct enables the usage of<br />
the opari[5] lib to add instrumentation for parallel regions and for<br />
constructs.</p>
<p style="text-align: justify;">This configure won&#8217;t generate MPI support, thus, if you want to generate MPI<br />
instrumentation, you should take a look at the documentation (good luck).</p>
<p style="text-align: justify;">Type make install, and it will generate the required files. The important thing<br />
here is to get the Instrumentation makefiles generated, which should reside on<br />
the ${arch}/lib/ subdir. You should have a makefile for each kind of tracing<br />
you wish to use. In my case, I have two makefiles Makefile.tau-icpc-pdt-openmp-trace and<br />
Makefile.tau-icpc-pdt-openmp-opari-trace.</p>
<p style="text-align: justify;">You can check that your configuration is OK by runing the tau_validate script,<br />
inside the main tau directory.</p>
<p style="text-align: justify;"><code><br />
$ ./tau_validate --html --table table.html x86_64 &amp;&gt; results.html<br />
</code></p>
<p style="text-align: justify;">Open results.html and go to the end: Green boxes means that the combination of<br />
trace and architecture will be OK. You should have green boxes on openmp and<br />
openmp-opari.</p>
<h3 style="text-align: justify;">Code instrumentation</h3>
<p style="text-align: justify;">Assuming you are using a Makefile, if you want to add profiling information to<br />
your code, you must include the previously-generated Makefile, and use its<br />
variables to enable the trace. TAU_COMPILER holds the instrumentation script.<br />
TAU_OPTIONS are compile-time values that changes the behaviour of the<br />
instrumentation. In this case, KeepFiles preserves the intermediate files (so<br />
you can see the instrumented code), and -optVerbose shows the compilation<br />
process step by step (WILL be large, but useful).  In this case, as we want<br />
OpenMP regions to be automatically instrumented, we use the Opari makefile.</p>
<p style="text-align: justify;"><code><br />
...<br />
include ~/PATH_TO_TAU/x86_64/lib/Makefile.tau-icpc-pdt-openmp-opari-trace </code></p>
<p style="text-align: justify;"><code> </code></p>
<p><code>TAU_OPTIONS = -optKeepFiles -optVerbose</code></p>
<p><code> </code></p>
<p style="text-align: justify;"><code>CC = $(TAU_COMPILER)$(TAU_OPTIONS) icc -openmp FC =<br />
$(TAU_COMPILER)$(TAU_OPTIONS) ifort -openmp LOADER =<br />
$(TAU_COMPILER)$(TAU_OPTIONS)   ifort -openmp<br />
...<br />
</code></p>
<p style="text-align: justify;">Run your makefile as usual, and you will get the instrumented code.</p>
<h3 style="text-align: justify;">Getting the traces</h3>
<p style="text-align: justify;">Now that you have produced an instrumented binary , you just need to run it as<br />
usual. As we are instrumenting OpenMP code, be sure to set the OMP_NUM_THREADS<br />
variable to the number of threads you want to use.</p>
<p style="text-align: justify;">When finished, you should have a trace file called trace.[0-9]+.trc for each<br />
thread. If you have only one, the instrumentation didn&#8217;t detect your parallel<br />
regions. If you have none, the code have been incorrectly instrumented!</p>
<h3 style="text-align: justify;">Showing the traces</h3>
<p style="text-align: justify;">TAU comes with a good visualization tool, called Jumpshot[6]. To use Jumpshot,<br />
you need Java. Jumpshot can read traces in Slog2 format, which is NOT the<br />
default format of TAU. You need to convert the traces first:</p>
<p style="text-align: justify;"><code><br />
# First step is to merge the per-thread traces to a single file<br />
$ PATH_TO_TAU/x86_64/bin/tau_merge   tautrace.0.0.* omp_trace.trc<br />
# Now, produce an slog2 file. Notice the tau.edf file, generated by the<br />
# previous tool<br />
$ PATH_TO_TAU/x86_64/bin/tau2slog2 omp_trace.trc tau.edf -o omp_trace.slog2<br />
</code></p>
<p style="text-align: justify;">This last file is the one that can be shown in jumpshot:</p>
<p style="text-align: justify;"><code> $ PATH_TO_TAU/x86_64/bin/jumpshot  omp_trace.slog2 </code></p>
<p style="text-align: justify;">You will have some interesting shots of the flow of the application,<br />
like shown in the image. Explaining the graphics is out of the<br />
scope of this post.</p>
<h2 style="text-align: justify;">OmpP</h2>
<p style="text-align: justify;">Detailed information about OpenMP regions can be shown using OmpP[7],<br />
a specific OpenMP Profiler.</p>
<h3 style="text-align: justify;">Setup and Config</h3>
<p style="text-align: justify;">Setup is quite straightforward. Just Download the last version from OmpP[7], and<br />
edit the Makefile.defs with the values for your machine. Then, run make<br />
and make install. You will have a directory with the OmpP installed.</p>
<h3 style="text-align: justify;">Instrumenting code</h3>
<p style="text-align: justify;">Manual instrumentation is possible, like in the case of TAU, but we will focus on<br />
automatic instrumentation. OmpP uses its own opari version to automatically do this.</p>
<p style="text-align: justify;">To add OmpP  information to your makefile, edit your makefile like in the example:</p>
<p style="text-align: justify;"><code><br />
OMPP = PATH_TO_OMPP/ompp/bin/kinst-ompp<br />
OMPPFLAGS= -IPATH_TO_OMPP/ompp/include/ -LPATH_TO_OMPP/home/rreyes/soft/ompp/lib/<br />
..<br />
CC = $(OMPP) icc<br />
FC = $(OMPP) ifort<br />
..<br />
CFLAGS = $(OMPPFLAGS) -O3<br />
FFLAGS = $(OMPPFLAGS) -O3<br />
</code></p>
<p style="text-align: justify;">Theoretically the second one is not needed, but, at least in my case, the includes<br />
were not added by the compilation script.</p>
<p style="text-align: justify;">When hitting make, you may get some complains about a missing header file. It seems<br />
to me that some error arises during the instrumentation, but the easiest way to<br />
solve it is to copy the contents of the include dir from ompp to one of your<br />
include directories.</p>
<h3 style="text-align: justify;">Getting the traces</h3>
<p style="text-align: justify;">Run your program as usual (don&#8217;t forget about the OMP_NUM_THREADS variable), and you<br />
will get an txt file, with detailed information about the program behaviour.</p>
<h3 style="text-align: justify;">Showing information</h3>
<p style="text-align: justify;">If you wish to watch a graphical version, you must change the default behaviour of<br />
OmpP to generate CSV files instead of ASCII. This can be accomplished by the follwing<br />
commmand:</p>
<p style="text-align: justify;"><code><br />
export OMPP_OUTFORMAT=CSV<br />
</code></p>
<p style="text-align: justify;">Then, re-run your application, and you will see that, instead of a txt file, a csv<br />
file is written.</p>
<p style="text-align: justify;">The paraprof[8] tool, from the previously installed TAU packaged can be used to see<br />
the results. Just load paraprof, and then open the csv file.<br />
Documentation</p>
<h3 style="text-align: justify;">Links</h3>
<p style="text-align: justify;">[0] http://www.project-text.eu/<br />
[1] http://en.wikipedia.org/wiki/Profiling_(computer_programming)<br />
[2] http://www.ibm.com/developerworks/library/l-gnuprof.html<br />
[3] http://en.wikipedia.org/wiki/Amdahl&#8217;s_law<br />
[4] http://www.cs.uoregon.edu/research/tau/home.php<br />
[5] http://www.fz-juelich.de/jsc/kojak/opari/<br />
[6] http://www.mcs.anl.gov/research/projects/perfvis/software/viewers/index.htm<br />
[7] http://www.cs.utk.edu/~karl/ompp.html<br />
[8] http://www.cs.uoregon.edu/research/tau/docs/paraprof/index.html</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=49</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Split a Latex Beamer file by frame</title>
		<link>http://www.ruyk.com/tech/?p=42</link>
		<comments>http://www.ruyk.com/tech/?p=42#comments</comments>
		<pubDate>Sat, 07 Nov 2009 18:25:03 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=42</guid>
		<description><![CDATA[Sometimes, when a presentation is getting too big for a file, I try to split the frames on several files, usually one file per slide. Being tired of doing this by hand, I&#8217;ve written a Perl script for doing that: #!/usr/bin/perl -w # Split a beamer file into several files, with one slide on each [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes, when a presentation is getting too big for a file, I try to split the frames on several files, usually one file per slide. Being tired of doing this by hand, I&#8217;ve written a Perl script for doing that:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
<span style="color: #666666; font-style: italic;"># Split a beamer file into several files, with one slide on each</span>
<span style="color: #666666; font-style: italic;">#           Ruymán Reyes Castro</span>
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> utf8<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$slide_num</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$ACTUAL</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$inside</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span>  <span style="color: #009900;">&#40;</span><span style="color: #339933;">&lt;&gt;;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/begin{frame}/</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #666666; font-style: italic;"># new file begins</span>
   <span style="color: #0000ff;">$slide_num</span><span style="color: #339933;">++;</span>
 <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elsif</span> <span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/frametitle{(.*)}/</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #0000ff;">$inside</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;"># Extract file name</span>
   <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$filename</span> <span style="color: #339933;">=</span> filenamize<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Writing: &quot;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$slide_num</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;_&quot;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$filename</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot; <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;"># create file</span>
   <span style="color: #000066;">open</span> ACTUAL<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;&gt;;&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;R&quot;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$slide_num</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;_&quot;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$filename</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;.tex&quot;</span> <span style="color: #b1b100;">or</span> <span style="color: #000066;">die</span> <span style="color: #0000ff;">$1</span><span style="color: #339933;">;</span>
   <span style="color: #000066;">print</span> ACTUAL <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>begin{frame} <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
   <span style="color: #000066;">print</span> ACTUAL <span style="color: #0000ff;">$_</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elsif</span> <span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/end{frame}/</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">print</span> ACTUAL <span style="color: #0000ff;">$_</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;"># End file</span>
    <span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Done. <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">close</span> ACTUAL<span style="color: #339933;">;</span>
    <span style="color: #0000ff;">$inside</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;"># Write to file</span>
    <span style="color: #000066;">print</span> ACTUAL <span style="color: #0000ff;">$_</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$inside</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Filenamize translates the frame title to a string suitable for naming a file</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> filenamize <span style="color: #009900;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">use</span> Encode<span style="color: #339933;">;</span>
   <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$in</span> <span style="color: #339933;">=</span> Encode<span style="color: #339933;">::</span><span style="color: #006600;">decode</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'utf-8'</span><span style="color: #339933;">,</span> <span style="color: #000066;">shift</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #0000ff;">$in</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">tr/ /_/</span><span style="color: #339933;">;</span>
   <span style="color: #0000ff;">$in</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">tr/áéíóúñ/aeioun/</span><span style="color: #339933;">;</span>
   <span style="color: #0000ff;">$in</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">tr/:/_/</span><span style="color: #339933;">;</span>
   <span style="color: #000066;">return</span> <span style="color: #0000ff;">$in</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It&#8217;s only a quick-solution, but maybe it&#8217;s useful for someone over there&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=42</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pssh-copy-id</title>
		<link>http://www.ruyk.com/tech/?p=30</link>
		<comments>http://www.ruyk.com/tech/?p=30#comments</comments>
		<pubDate>Fri, 07 Aug 2009 17:34:56 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=30</guid>
		<description><![CDATA[ssh-copy-id[1] is a well-known command for system administration, specially for those deeply involved in the clustering field. It is common, in a cluster environment, to use ssh keys instead of  passwords on multiple machines, so we can move from one machine to another without the need of typing a password. Even you can use a [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-family: 'Times New Roman'; font-size: 16px; line-height: normal;"> </span></p>
<div style="font-family: Verdana; font-size: 14pt; background-color: #ffffff; min-height: 1100px; counter-reset: __goog_page__ 0; line-height: normal; padding: 0px; margin: 6px;"><span style="font-family: 'Times New Roman';"></p>
<div style="background-image: initial; background-repeat: initial; background-color: #ffffff; margin: 0px;">
<p style="margin: 0px;"><span><strong><span style="font-family: Verdana;"><span style="font-size: large;">ssh-copy-id[1]</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;"> is a well-known command for system administration, specially for those deeply involved in the clustering field. It is common, in a cluster environment, to use ssh keys instead of  passwords on multiple machines, so we can move from one machine to another without the need of typing a password. Even you can use a key for limiting the access of the user to an specified command, instead of allowing the user to spawn a full shell (as you may see in [1] or [2]) .</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">SSH key pairs are composed by two keys: the public key and the private key. For ssh keys to work, you will need to publish the public key on the remote machine, so it can check if you has the correct private key when accessing. </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">Never</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;"> publish or make public your private key, as this is an enormous security risk. To publish without risk, you can use the shell script </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">ssh-copy-id</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;">, supplied with the openssh package, that will connect to a remote machine  and write the public key.</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">When you have multiple machines, as in a cluster environment, you need to publish your public key in multiple places. The first approximation may be writing a for script with the mentioned </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">ssh-copy-id</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;">, but this faces an awkward problem: Either you have to type multiple times the same key, or you have to pass it insecurely, for example:</span></span></span></p>
<blockquote style="padding: 10px; border: 1px dashed #dddddd;">
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">for host in host1 host2 host3; do</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">yes &#8216;MyPassword&#8217; | ssh-copy-id $host</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">done</span></span></span></p>
</blockquote>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">Using this way, your password is exposed to all users (just by issuing a ps command), so it is not a Good Practice.</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">PhD. Casiano Rodriguez Leon, exposed this problem to me during one of my PhD Courses, and suggested doing a Perl script to make this publishing key issue faster and more secure.</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">After some work, We&#8217;ve come up with a solution called </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">pssh-copy-id</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;">, which is a perl script / library, published on google code [4]. We hope to refine and clean the code, so it would be accepted on CPAN and freely available to all the community.</span></span></span></p>
<p style="margin: 0px;"><span><strong><span style="font-family: Verdana;"><span style="font-size: large;">pssh-copy-id</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;">, currently work-in-progress, enables to use a syntax similar to </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">ssh-copy-id</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;"> to publish the key, for example:</span></span></span></p>
<blockquote style="padding: 10px; border: 1px dashed #dddddd;">
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">$ pssh-copy-id  host1 host2 host3</span></span></span></p>
</blockquote>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">Will ask four your password (assuming is the same for all of the hosts) , and publish the default key on all the machines listed. The password won&#8217;t be exposed in any way*. In addition,</span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">pssh-copy-id</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;"> will check if the key has been already published, in which case it won&#8217;t be repeated. Also, </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">pssh-copy-id </span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;">supports host without password, in example, a host with another key published.</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">Currently, </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">pssh-copy-id</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;"> supports also the host definition syntax of </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">net-parscp</span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;">[5], which allows us to use regular expression to define hosts, the same command as before could be written like this:</span></span></span></p>
<blockquote style="padding: 10px; border: 1px dashed #dddddd;">
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">$ pssh-copy-id host1..3</span></span></span></p>
</blockquote>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">Future versions of </span></span><strong><span style="font-family: Verdana;"><span style="font-size: large;">pssh-copy-id </span></span></strong><span style="font-family: Verdana;"><span style="font-size: large;">will make the process of key publishing parallel, by spawning one process by host, so the process of publishing the key to several host will be faster.</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">This utility could be a quite useful tool for system administrators, that will enable them to publish and distribute keys faster, or integrate on bigger a script (like we&#8217;re doing on the SAII) to simplify the user key distribution problem.</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">Notes:</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">* except maybe under a process memory dump, which has not been tested</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">References:</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">[1] </span></span><a style="color: #551a8b;" href="http://linux.die.net/man/1/ssh-copy-id"><span style="font-family: Verdana;"><span style="font-size: large;">http://linux.die.net/man/1/ssh-copy-id</span></span></a></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">[2] http://oreilly.com/catalog/sshtdg/chapter/ch08.htm</span></span></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">[3]</span></span><a style="color: #551a8b;" href="http://blog.ganneff.de/blog/2007/12/29/ssh-triggers.html"><span style="font-family: Verdana;"><span style="font-size: large;">http://blog.ganneff.de/blog/2007/12/29/ssh-triggers.html</span></span></a></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">[4] </span></span><a style="color: #551a8b;" href="http://code.google.com/p/pssh-copy-id/"><span style="font-family: Verdana;"><span style="font-size: large;">http://code.google.com/p/pssh-copy-id/</span></span></a></span></p>
<p style="margin: 0px;"><span><span style="font-family: Verdana;"><span style="font-size: large;">[5] </span></span><span style="font-family: Verdana;"><span style="font-size: large;"><a style="color: #551a8b;" href="http://code.google.com/p/net-parscp/">http://code.google.com/p/net-parscp/</a></span></span></span></p>
<div><span style="font-family: Verdana; font-size: large;"><span style="font-size: 18px;"><br />
</span></span></div>
</div>
<p></span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=30</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some notes about Django</title>
		<link>http://www.ruyk.com/tech/?p=24</link>
		<comments>http://www.ruyk.com/tech/?p=24#comments</comments>
		<pubDate>Fri, 14 Nov 2008 22:26:07 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=24</guid>
		<description><![CDATA[WARNING!: This post has been written in English, because I want to practice. If you find some mistake (orthographic, grammatical, whatever), please, don&#8217;t laugh and tell me where is it. Thanks for your collaboration! In the SAII[1], we are currently developing applications using Django Framework[2]. Django is an open source application framework, written in Python. It [...]]]></description>
			<content:encoded><![CDATA[<p><strong>WARNING!: This post has been written in English, because I want to practice. If you find some mistake (orthographic, grammatical, whatever), please, don&#8217;t laugh and tell me where is it. Thanks for your collaboration!</strong></p>
<p>In the SAII[1], we are currently developing applications using Django Framework[2]. Django is an open source application framework, written in Python. It follows the model-view-controller design pattern (MVC[3]). We chose Django because it&#8217;s a powerful environment that allow us to quickly pass from the UML class diagram to the model structure, and after that, it&#8217;s only a matter of creating the admin interface with two or three simple calls. This offers you a quickly starting point, and, if you are writing a small application, you&#8217;ll only need to customize a few aspects of the admin interface.</p>
<div class="wp-caption alignleft" style="width: 127px"><a href="www.djangoproject.com"><img title="Django Logo" src="http://media.djangoproject.com/img/site/hdr_logo.gif" alt="Django Logo" width="117" height="41" /></a><p class="wp-caption-text">Django Logo</p></div>
<div>
<p>Recently, Django has reached the 1.0 version. This version is a huge milestone for the Django team, who started three years ago with only some code lines. Now Django have more than 4000 code commits, 40.000 lines of documentation and a really active comunity supporting the proyect.</p>
<p>However, perhaps you&#8217;ll need to use some features that are not in the 1.0 version. If that is your case, you&#8217;ll need to use the Django subversion[4], which is the easiest way to get the last version of the proyect. This version is usually  stable, and you can use it without too much trouble. But be careful: Sometimes the trunk version will have some api changes, that could break your application, or third party applications. So, if you want to develop and application, and don&#8217;t need the cutting-edge version of the subversion, I would recommend you using the stable release, 1.0, or the next 1.0.1, which contains some bugfixes.</p>
<p>In the SAII, we are in a dangerous position right now, because we need some third party applications (django_xmlrpc and tagging) that need features of the subversion version. This has lead us to some problems, which we need to fix manually, &#8220;diving&#8221; into the Django code with the debugger. All of the cases were solved by updating the django trunk or the third party application package. Our plan at this moment is to pick the current trunk revision, and use that as our &#8220;stable&#8221; revision, freezing the state of the framework until we&#8217;ll need some extra feature.</p>
<p>In conclusion, Django is a really good framework for web applications. Don&#8217;t hesitate to use it in any size projects. One of the applications we developed was used by 250 users simultaneusly during a short time period, and it worked flawlessly. I&#8217;ll try to run some benchmarks with the new application, which will have many more users, to measure the charge on the system.</p>
<p>[1] www.saii.ull.es</p>
<p>[2] www.django.com</p>
<p style="text-align: left;" dir="ltr">[3] http://en.wikipedia.org/wiki/Model-view-controller</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=24</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Factorías de clases en Python</title>
		<link>http://www.ruyk.com/tech/?p=23</link>
		<comments>http://www.ruyk.com/tech/?p=23#comments</comments>
		<pubDate>Thu, 01 May 2008 14:47:53 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=23</guid>
		<description><![CDATA[Hay veces que necesitas crear en tiempo de ejecución clases nuevas (Ojo, no nuevas instancias de una clase, sino clases en si mismas). Es útil cuando las clases se tienen que generar en función del contenido, o cuando hay que generar muchas clases parecidas y no queremos estar escribiendo. Un ejemplo es el framework para [...]]]></description>
			<content:encoded><![CDATA[<p>Hay veces que necesitas crear en tiempo de ejecución clases nuevas (Ojo, no nuevas instancias de una clase, sino clases en si mismas). Es útil cuando las clases se tienen que generar en función del contenido, o cuando hay que generar muchas clases parecidas y no queremos estar escribiendo.</p>
<p>Un ejemplo es el framework para aplicaciones web Django. En este framework, se pueden generar fomularios HTML automágicamente, por ejemplo, para crear un formulario html que permita introducir los datos del modelo Tutu, simplemente hay que hacer una clase del tipo:</p>
<pre class="literal-block">&gt;&gt;&gt; class TutuForm(ModelForm):
...     class Meta:
...         model = Tutu</pre>
<p>El problema surge cuando tenemos muchos modelos  y tenemos que generar autoformularios para todos. Si tenemos que hacer esta clase para cada uno, se nos hace el código muy grande, y tenemos que trabajar con un esquema fijo de urls por ejemplo.</p>
<p>En este caso, una mejor aproximación es utilizar el concepto de Factoría de Clases, es decir, una función (o clase incluso) que genera nuevas clases en tiempo de ejecución. Es posible hacerlo en varios lenguajes, por ejemplo Perl, pero la belleza de la sintáxis de Python lo hace realmente sencillo y claro:</p>
<pre>def formClassFactory(modelName):</pre>
<pre>   """ Función que genera clases autoformulario en base al nombre del modelo del que queremos el formulario """</pre>
<pre>   # Buscamos la clase que corresponde al modelo</pre>
<pre>   modelClass = getModel(modelName)</pre>
<pre>   # Si no la encuentra, no devolvemos ninguna</pre>
<pre>   if modelClass == None:</pre>
<pre>      print "No existe un modelo para esa clase"</pre>
<pre>      return None</pre>
<pre>   else:</pre>
<pre>      print "Model Class" + str(modelClass)</pre>
<pre>   # creamos la clase fantasma (sólo tiene ámbito local)</pre>
<pre>   class _innerFormClassTemplate(ModelForm):</pre>
<pre>      class Meta:</pre>
<pre>	 # Le injertamos el atributo modelo con la clase</pre>
<pre>         model = modelClass</pre>
<pre>         exclude = ('grupo','id', 'user')</pre>
<pre>   # Devolvemos la clase injertada, con la que podemos definir el formulario modelo del método que queramos</pre>
<pre>   return _innerFormClassTemplate</pre>
<p>El código es muy pythónico y claro, pero aún así lo cuento un poco.  Como se dice en la docstring, la función genera clases de formulario automáticamente en función del nombre del modelo que queramos. Por ejemplo, si tenemos un modelo que se llama Tutu, esta  función devolverá una clase que genere un formulario, y que excluya tres campos que no queremos que aparezcan.</p>
<p>Para ello, primero obtiene la referencia a la clase cuyo nombre tenemos en una cadena. Se podría hacer con un getattr directamente, pero utilizando la función getModel se realizan ciertas comprobaciones de seguridad que no vienen al caso.  Luego comprobamos que la clase devuelta no sea nula, porque en ese caso no existiría el modelo del que queremos generar el formulario.</p>
<p>Aquí es donde aparece El Truco. Creamos una clase, con un nombre cualquiera, con la forma que queremos utilizar. Ésta clase tiene ámbito local a la función, así que sólo existe (a priori) en la función local. Aprovechando que tenemos la variable modelClass, fijamos el valor del atributo model de la clase Meta a modelClass, para que la clase nos genere un formulario modelo de la clase. Lo que hacemos finalmente es que la función nos devuelva una referencia a la clase que hemos creado. Como existe esa referencia, la clase sigue existiendo (recordemos que al ser un lenguaje interpretado, las variables existen mientras hayan referencias hacia ellas), y la podemos utilizar como una nueva clase  desde el lugar donde hayamos invocado a la función.</p>
<p>En el momento de invocar a la función y obtener la clase, podemos crear una instancia de la misma, como por ejemplo:</p>
<pre>  form = formClassFactory(_type)(instance = grp)</pre>
<p>Como hemos visto, una factoría de clases es una forma muy cómoda de gestionar la creación de muchas clases similares, ahorrándo código y tiempo, sin poner en peligro la legibilidad.</p>
<p>Algunos enlaces para ampliar:</p>
<p>[1] http://www.ibm.com/developerworks/linux/library/l-pymeta.html?S_TACT=105AGX03&amp;S_CMP=ART</p>
<p>[2] http://rgruet.free.fr/PQR25/PQR2.5.html</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=23</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thunderbird, Lightning y Google Calendar</title>
		<link>http://www.ruyk.com/tech/?p=22</link>
		<comments>http://www.ruyk.com/tech/?p=22#comments</comments>
		<pubDate>Tue, 18 Mar 2008 14:30:07 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[google calendar]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[thunderbird]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=22</guid>
		<description><![CDATA[Recientemente he estado utilizando Thunderbird y Google Calendar para gestionar el correo con el primero, y las citas con el segundo. A veces, la interfaz de Google Calendar se me hace pesada, no sólo porque hay que cargar el navegador, sino porque ciertas cosas no puedes hacerlas, como por caejemplo, copiar una cita de un [...]]]></description>
			<content:encoded><![CDATA[<p> Recientemente he estado utilizando <a href="http://en.www.mozilla.com/en/thunderbird/" title="Thunderbird" target="_blank">Thunderbird</a> y <a href="http://www.google.com/calendar/" title="Google Calendar" target="_blank">Google Calendar</a> para gestionar el correo con el primero, y las citas con el segundo.  A veces, la interfaz de Google Calendar se me hace pesada, no sólo porque hay que cargar el navegador, sino porque ciertas cosas no puedes hacerlas, como por caejemplo, copiar una cita de un día a otro (tienes que crearla de nuevo).</p>
<p>El otro día conocí la extensión <a href="http://www.mozilla.org/projects/calendar/lightning/" title="Lightning">Lightning</a> de Thunderbird, que permite integrar la funcionalidad de <a href="http://www.mozilla.org/projects/calendar/sunbird/" title="Sunbird" target="_blank">Sunbird</a> (gestor de calendarios de mozilla). Está muy interesante, y funciona bastante bien. Tiene todas las características habituales: Eventos, tareas, vistas de calendario, etc.</p>
<p>Pero claro, tengo todo en google calendar, que tiene la ventaja de poder acceder a él desde cualquier sitio, así que no me interesaba pasarme por completo a Lightning.</p>
<p>Aunque Google Calendar permite exportar en formato ical o xml, Lightning por defecto sólo permite leer los calendarios en sólo lectura. El problema es que para escribir en el calendario, tienes que autentificarte como usuario de google (¡y no es una característica estándar precisamente!)</p>
<p>Para permitir importar los calendarios en modo de escritura, existe una extensión de Lighting (y Sunbird) llamada muy originalmente <em><a href="https://addons.mozilla.org/en-US/thunderbird/addon/4631" title="Provider for Google Calendar">Provider for Google Calendar</a>. </em>Con sólo poner la URL privada del calendario de google en lugar de la pública, y proporcionar el usuario y contraseña cuando se nos solicite, podremos acceder tranquilamente a los calendarios, y modificarlos sin problema.</p>
<p>Cuidado con las versiones. <em>Provider for Google Calendar</em> sólo es operativa con las versiones más recientes de Lightning y de Thunderbird. La versión que se encuentra en el repositorio de Ubuntu es basura, así que es mejor si la instalan a mano.</p>
<p><a href="http://bfish.xaedalus.net/?p=239" title="Tutorial Provider">Para terminar, aquí</a> hay un tutorial muy sencillo de cómo utilizar el plugin. Que lo disfruten si les interesa ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=22</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Y ahora, en dreamhost</title>
		<link>http://www.ruyk.com/tech/?p=19</link>
		<comments>http://www.ruyk.com/tech/?p=19#comments</comments>
		<pubDate>Sat, 02 Feb 2008 19:02:00 +0000</pubDate>
		<dc:creator>Ruyk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ruyk.com/tech/?p=19</guid>
		<description><![CDATA[En el primer post que puse (hace algún tiempo) en este blog, mostraba las fotos de como tenía mi cuartucho en el garage, con la supuesta infraestructura de servidor y demás. El servidor que estaba encima del armario, hacía de servidor web, de correo, de ssh, de DNS, de Lineage 2 , y de algunas [...]]]></description>
			<content:encoded><![CDATA[<p>En el <a href="http://www.ruyk.com/tech/?p=1" title="Primer post" target="_blank">primer post que puse</a> (hace algún tiempo) en este blog, mostraba las fotos de como tenía mi cuartucho en el garage, con la supuesta infraestructura de servidor y demás.</p>
<p>El servidor que estaba encima del armario, hacía de servidor web, de correo, de ssh, de DNS, de <a href="http://www.lineage2.com/" title="Lineage 2">Lineage 2</a> , y de algunas cosas más que ya no recuerdo. Estaba configurado con un Gentoo Hardened, que (supuestamente) era bastante seguro.</p>
<p>Sin embargo, cada vez me llevaba más tiempo mantenerlo, con las actualizaciones de seguridad que fallaban, con discos duros que se estropeaban, etc. Pensé en cambiarlo por otro servidor, pero eso me llevaría bastante tiempo, así que recordé las palabras de mi maestro <a href="http://www.jovianstorm.com/" title="Jake">Jake</a> hace tiempo, en las que me recomendaba que usara dreamhost y me dejara de problemas.</p>
<p>Así que lo hice, contraté 3 años de hosting, y ahora, poco a poco, estoy migrando las cosas aquí. Primero los blogs, luego los repositorios de subversion, y finalmente las backups de las prácticas. Espero que esté todo para finales de febrero, para empezar con buen pié el segundo cuatrimestre.</p>
<p>Ahora en casa no tengo servidor. La configuración de red (firewall, dhcp, etc) la gestionan ahora dos routers, el Linksys ADSL2 Gateway AG241 y el Linksys WRT54G que tengo con el firmware de HyperWRT.</p>
<p>El primero se encarga de la conexión al ADSL y de la red del cuartucho. Tiene el cortafuegos principal y es el que tiene el dhcp. A éste router está conectado el otro, a través del cable más largo de mi casa, que llega hasta el cuarto de la tele.  El WRT se encarga de la red Wifi y la red pequeña para los windows, donde se engancha mi familia sin riesgo de sufrir el acoso de los hackers. Aquí también está enchufada la <a href="http://uk.playstation.com/ps3/" title="PlayStation 3">Playstation 3</a>, pero en una <a href="http://en.wikipedia.org/wiki/DMZ" title="DMZ">DMZ</a>, para no tener problemas con el juego online.</p>
<p>En la imagen aparece un esquema sencillo de como está la red ahora.</p>
<p><a href="http://www.ruyk.com/tech/wp2-content/uploads/2008/02/esquemacasa.png" title="Esquema de la red de casa"><img src="http://www.ruyk.com/tech/wp2-content/uploads/2008/02/esquemacasa.png" alt="Esquema de la red de casa" /></a></p>
<p>Ya describiré las máquinas que hay en detalle, sobre todo la PlayStation y Endymion, que son las que estoy &#8220;tocando&#8221; últimamente. Venturis e Hyperion son las máquinas viejas, que no tengo conectadas, pero que usaré para cosas más adelante, cuando tenga tiempo.</p>
<p>Espero tener menos problemas con esta configuración, y así poder dedicar mi tiempo a cosas más molonas que se puedan contar aquí ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ruyk.com/tech/?feed=rss2&#038;p=19</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

