<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns="http://purl.org/rss/1.0/">




    



<channel rdf:about="http://blog.redturtle.it/english/RSS">
  <title>English</title>
  <link>http://blog.redturtle.it</link>

  <description>
    
      
    
  </description>

  

  
            <syn:updatePeriod>daily</syn:updatePeriod>
            <syn:updateFrequency>1</syn:updateFrequency>
            <syn:updateBase>2012-05-08T16:02:35Z</syn:updateBase>
        

  

  <image rdf:resource="http://blog.redturtle.it/logo.png"/>

  <items>
    <rdf:Seq>
      
        <rdf:li rdf:resource="http://blog.redturtle.it/how-to-automatically-refresh-your-database-in-silent-mode"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/funkload-simple-buildout-to-run-your-test"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/merging-odf-files-using-xdocreport-and-xpages"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/migrating-dexterity-items-to-dexterity-containers"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/caution-2013-meteor-will-hit-the-world-wide-web"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/buildout-plone-vs-forefront-tmg-using-cntlm"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/how-to-write-custom-plugin-for-nagios-and-check_mk"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/lotus-domino-twitter-way-for-mobile-approach"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/angel-of-arnhem"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/how-to-integrate-d3-graphic-library-in-lotus-domino-environment"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/plone-conference-2012-from-redturtles-perspective"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/plone-registry-strikes-back"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/plone.app.registry-how-to-use-it-and-love-it"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/earthquake-plone-to-the-rescue"/>
      
      
        <rdf:li rdf:resource="http://blog.redturtle.it/slow-plone-site-lets-use-haufe.requestmonitoring"/>
      
    </rdf:Seq>
  </items>

</channel>


  <item rdf:about="http://blog.redturtle.it/how-to-automatically-refresh-your-database-in-silent-mode">
    <title>How to automatically refresh your database in "silent mode"</title>
    <link>http://blog.redturtle.it/how-to-automatically-refresh-your-database-in-silent-mode</link>
    <description>Break away from dependence on the Lotus Notes client to update your database: an easy tutorial to get applications with the latest update every morning</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p><strong>Scenario</strong>: a development server, a release server and many production customers' servers: nothing more classic.</p>
<p class="breakText" id="_mcePaste">Every time a change is deployed on the release server, the best thing would be to "push" it automatically on production server, or as soon as possible (at least).</p>
<p> </p>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText">We know that Lotus Domino provides the "Refresh design tool", but it requires a Lotus client installed and open, and a manual operation.</div>
<p class="breakText">Maybe you can work with replicas of the template, but, in any case, the "optimum" would be:</p>
<div id="_mcePaste"></div>
<div id="_mcePaste">
<ul>
<li>break away from the dependence of the Lotus Notes client</li>
<li>schedule the operation in automatic mode.</li>
</ul>
</div>
<p>So what?</p>
<h2>Many solutions found over the Web, but...</h2>
<p>As reported in this <a class="external-link" href="http://www-10.lotus.com/ldd/nd6forum.nsf/55c38d716d632d9b8525689b005ba1c0/6128e935dae691d580256df9003fb5a4?OpenDocument">thread</a>, automatic refresh design is something desired, perhaps to have something scheduled (agent), but even if low level Notes API are provided, it always requires an opened client and, in this case, a Windows client (API uses <i>dll</i>)!</p>
<blockquote class="pullquote"><i>Typically </i><i>'load convert' command is used for mail database</i></blockquote>
<p>I remembered something about notes mail database administration, and a very cool stuff to upgrade mail templates, with this command:</p>
<pre>load convert -n maildb.nsf * template.ntf</pre>
<p>So, why not apply the same method to <strong>not-mail</strong> database?</p>
<p>I've investigated a lot, I've also opened a discussion on <a class="external-link" href="http://stackoverflow.com/questions/14998328/mail-conversion-utility-of-a-non-mail-database-using-remote-server">Stackoverflow</a> and many authoritative people (<a class="external-link" href="http://www.poweroftheschwartz.com/">Richard H. Schwartz</a>, <a class="external-link" href="http://per.lausten.dk/blog/">Per Henrik Lausten</a>) answered me about different approaches, but I think that "load convert way" could be a good solution.</p>
<p>Be careful! If you try this, you can run into some problems: below I'll try to answer at the most commons I've experienced, and steps to resolve them.</p>
<h3>Q:</h3>
<p>What about if templates are on remote server?</p>
<h3>A:</h3>
<p>It's possible to directly refer the remote template, using this syntax:</p>
<pre>load convert -n mydatabase.nsf * remoteserver!!template.ntf</pre>
<p>where <i><strong>remoteserver </strong></i>is abbreviated name (e.g. <i>removeServerName/OrgUnit/Org</i>).</p>
<p>NOTICE: database and remote template could also be located in subfolder, so you can use:</p>
<pre>load convert -n dir1/dir2/mydatabase.nsf * remoteserver!!dir3/dir4/template.ntf</pre>
<p> </p>
<h3>Q:</h3>
<p>When I send the command, I obtain this error: <i>'Mail Upgrade Failed: Unable to open design template file ......Unable to find path to server'</i>"</p>
<h3>A:</h3>
<p>On production server, you need to create a connection to the release server, as shown in pictures:</p>
<p><img alt="connections" class="image-inline" src="http://blog.redturtle.it/uploads/copy_of_connections.JPG" title="connections" /></p>
<p> </p>
<h3>Q:</h3>
<p>After the connection is done, I obtain this error: 'The Address Book does not contain a cross certificate capable of validating the public key'</p>
<h3>A:</h3>
<p>A cross-certification between organizations is needed, in both directions (release server to production server and vice-versa), using <i>server.id </i>and <i>cert.id.</i></p>
<h2>Ready to go!</h2>
<p>All the prerequisites for a correct communication are made.</p>
<p>Now is possible to schedule the refresh command whenever you want, in your preferred way, for example:</p>
<ul>
<li>making a <i>program</i> (see <a class="external-link" href="http://www-01.ibm.com/support/docview.wss?uid=swg21088932">here</a>)</li>
<li>with a <i>scheduled agent</i> that send commands to server</li>
</ul>
<p>Next lines show how to do this in a Java agent:</p>
<pre>String command = "load convert -n mydatabase.nsf * remoteserver!!template.ntf";
System.out.println(session.sendConsoleCommand("", command));</pre>
<p>That's all! Feel free to let me know what do you think about this approach. Any comment/review will be appreciated!</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Baglioni</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Lotus</dc:subject>
    
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>Domino</dc:subject>
    
    <dc:date>2013-04-12T13:30:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/funkload-simple-buildout-to-run-your-test">
    <title>Funkload: a simple buildout to spread and run your test!</title>
    <link>http://blog.redturtle.it/funkload-simple-buildout-to-run-your-test</link>
    <description>Load testing can be one of the key for a successful website deployment. Moreover it can help to solve many situations. Let's see a way to spread your tests!</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Recently we faced a performance issue on a <strong>Plone </strong>site, which has been reported to be slower than expected.</p>
<p>The application, after a migration to a new hardware, has shown to be a bit lazy compared to the expectations.</p>
<p>Because of the weird behaviour and confident on our <strong>Plone </strong>installation, we assumed a hardware misconfiguration.<br /> But without evidence (numbers in this case), a claim is merely an opinion.</p>
<p>So, to get ride of the problem, we decided to perform multiple load test on different servers, and then compare the results.</p>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText">The easiest and fast way to get the job done has been achieved with a simple <i>buildout</i> used to spread <strong>Funkload</strong> on many other servers with the same hardware requirements, each one running a Plone site clone. Of course, in order to compare the performance, every server has to meet the same hardware requirements.</div>
<p> </p>
<h3>Funkload</h3>
<div><a class="external-link" href="http://funkload.nuxeo.org/">Funkload</a> is a powerful functional and load web tester, easy to install and well documented. I'm not going deep on details of all its functionality in this post, because in our case the two standard commands <strong>fl-run-bench</strong> and <strong>fl-build-report</strong> have been enough for the purpose, but if you are interested there are many guides online that can help you:</div>
<div></div>
<div><a href="http://funkload.nuxeo.org/">http://funkload.nuxeo.org/</a></div>
<p><a href="http://funkload.nuxeo.org/"></a><a href="http://ziade.org/2011/07/27/how-to-stress-test-your-app-using-funkload-part-1/">http://ziade.org/2011/07/27/how-to-stress-test-your-app-using-funkload-part-1</a></p>
<p>So, let's see how to set a Funkload test within a <i>buildout.</i></p>
<div>As usual the starting point is the <a class="external-link" href="https://pypi.python.org/pypi/virtualenv">virtualenv</a> environment:</div>
<pre>git clone https://github.com/nicolasenno/funkload.buildout
cd funkload.buildout<br />virtualenv --no-site-packages .<br />. bin/activate
</pre>
<p>Then the buildout.cfg (<a class="external-link" href="https://github.com/nicolasenno/funkload.buildout">download</a> from github):</p>
<div></div>
<pre>[buildout]
parts = 
    bench-tools
    gnuplot
    versions = versions<br />
[bench-tools]
recipe = zc.recipe.egg:scripts
eggs =
    docutils
    funkload 
    tcpwatch
initialization =
import os
os.environ['TCPWATCH'] = "${buildout:bin-directory}/tcpwatch"

[gnuplot]
recipe = zc.recipe.cmmi
url = http://sourceforge.net/projects/gnuplot/files/gnuplot/4.6.2/gnuplot-4.6.2.tar.gz/download
configure-options = --bindir=${buildout:directory}/bin<br />
[versions]
funkload = 1.16.1<br /> </pre>
<p><strong>Gnuplot</strong> can be installed directly from buildout, as suggested by  Alessandro Pisa on his <a class="external-link" href="http://blog.redturtle.it/fix-funkload-report-generation-problems-by-upgrading-gnuplot">blog post.</a></p>
<div>Finally, once Funkload is ready, we can create a test:</div>
<pre>import unittest
from random import random
from funkload.FunkLoadTestCase import FunkLoadTestCase

PAGES = (('Homepage', ''),
         ('path1', 'contacts'),
         ('path2', 'media'),
         )

class Site(FunkLoadTestCase):
    """This test use a configuration file Site.conf."""

    def setUp(self):
        """Setting up test."""
        self.server_url = self.conf_get('main', 'url')

    def test_app(self):
        ''' site path
        '''
        server_url = self.server_url

        for title, page in PAGES:
            url = "/".join((server_url, page))
            self.get(url, description='Get %s' % title)
</pre>
<p>Then we can use a Makefile to automate the launch process:</p>
<pre>LOG_HOME := var/funkload/log
REPORT_HOME := var/funkload/data

ifdef URL
    FLOPS = -u $(URL) $(EXT)
else
    FLOPS = $(EXT)
endif

ifdef REPORT_HOME
    REPORT = $(REPORT_HOME)
else
    REPORT = report
endif

all: test

test: start test-app

bench: start bench-app

start:
    mkdir -p $(REPORT)  $(LOG_HOME)

test-app:
    fl-run-test -d --debug-level=3 --simple-fetch site_test.py Site.test_app $(FLOPS)

bench-app:
    fl-run-bench --simple-fetch site_test.py Site.test_app -c 1:5:10:15:20:30:40:50 -D 45 -m 0.1 -M .5 -s 1 $(FLOPS)
    fl-build-report $(LOG_HOME)/site-bench.xml --html -o $(REPORT)

clean:</pre>
<p>If you prefer, as an improvement, you can generate this file within the <i>buildout</i> itself.<br />Take a look to <a class="external-link" href="https://pypi.python.org/pypi/collective.recipe.template">collective.recipe.template</a> for more information.</p>
<p>Here we are!<br /> A couple of shell commands and you will be ready to run the test.</p>
<p>From your <i>buildout</i> directory, type:</p>
<pre>make test
make test URL=http://override-url/
make bench
</pre>
<p>At this point a full report will be ready in "{buildout dir}/var/funkload/data" (path depends on your configuration).</p>
<h3>Conclusion</h3>
<p>As you can see install and run a <strong>Funkload</strong> load test it's just matter of few steps. <br /> Thanks to it, we have been able to prove our thesis with numbers.</p>
<p>I think it's not a bad idea add it into my checklist of things to do for every site deployment. It could become useful in many other cases.</p>
<h3>Recommended reading</h3>
<p><a href="http://blog.redturtle.it/how-to-write-funkload-test-in-few-minutes">http://blog.redturtle.it/how-to-write-funkload-test-in-few-minutes</a></p>
<p><a href="http://www.martinaspeli.net/articles/tools-for-a-successful-plone-project">http://www.martinaspeli.net/articles/tools-for-a-successful-plone-project</a></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Nicola Senno</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>web</dc:subject>
    
    
      <dc:subject>funkload</dc:subject>
    
    
      <dc:subject>Monitoring</dc:subject>
    
    
      <dc:subject>python</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2013-03-26T08:10:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/merging-odf-files-using-xdocreport-and-xpages">
    <title>Merging odf files using XDocReport and XPages</title>
    <link>http://blog.redturtle.it/merging-odf-files-using-xdocreport-and-xpages</link>
    <description>Often there is the need to create documents from templates, and the need to fill these templates with data available from other sources: let's take a look at this brief solution </description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>In this scenario, we have a <a class="external-link" href="https://www.google.it/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;ved=0CDIQFjAA&amp;url=http%3A%2F%2Fit.wikipedia.org%2Fwiki%2FOpenDocument&amp;ei=1fwhUej8D4fesgaG_YHgDA&amp;usg=AFQjCNFsaJsTx0KGBA-7HBgvr74IKbUtZw&amp;bvm=bv.42553238,d.Yms">odf template</a> to merge with data.</p>
<p><a class="external-link" href="https://www.google.it/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;ved=0CDIQFjAA&amp;url=http%3A%2F%2Fit.wikipedia.org%2Fwiki%2FOpenDocument&amp;ei=1fwhUej8D4fesgaG_YHgDA&amp;usg=AFQjCNFsaJsTx0KGBA-7HBgvr74IKbUtZw&amp;bvm=bv.42553238,d.Yms"></a></p>
<p>Working in the Lotus Domino environment, one way to achieve this goal could be a server-side component invoked by an <strong>XPagdies</strong>, to make the casting process: first, I need something in Java that could do the job for me, and after some search I came across <a class="external-link" href="http://code.google.com/p/xdocreport/">XDocReport</a>.</p>
<blockquote class="pullquote">XDocReport means XML Document reporting</blockquote>
<p class="breakText"><i><strong>XDocReport </strong>provides Java API to merge XML document created with MS Office (docx, pptx) or OpenOffice (odt), LibreOffice (odt) with a Java model to generate report and convert it in another format (PDF, XHTML...).</i></p>
<p class="breakText">Basicly, to make the template, main steps are:</p>
<ol style="padding-left: 25px; ">
<li>create a <strong>template document</strong> with MS Word (docx) or OpenOffice (odt, ods)</li>
<li>compose the body of the document itself with <strong>variables </strong>to fill in</li>
<li>use <strong><a href="http://velocity.apache.org/" rel="nofollow">Velocity</a> </strong>or<strong> <a href="http://freemarker.sourceforge.net/" rel="nofollow">Freemarker</a> syntax</strong> to set variables to replace.</li>
</ol>
<p><br />In this case, I opted to use Velocity inside an ODF file.</p>
<p>Now let's start by explaining how to set up the whole project.</p>
<h3>Installing server libraries</h3>
<p>External libraries (.jar) that serve the purpose have been installed in the installation directory of the Domino server (<i><strong>jvm/lib/ext</strong> </i>path).</p>
<p>These are the files:</p>
<pre>commons-collections-3.2.1.jar
commons-lang-2.4.jar
fr.opensagres.xdocreport.converter-1.0.0.jar
fr.opensagres.xdocreport.converter.odt.odfdom-1.0.0.jar
fr.opensagres.xdocreport.core-1.0.0.jar
fr.opensagres.xdocreport.document-1.0.0.jar
fr.opensagres.xdocreport.document.odt-1.0.0.jar
fr.opensagres.xdocreport.itext.extension-1.0.0.jar
fr.opensagres.xdocreport.template-1.0.0.jar
fr.opensagres.xdocreport.template.velocity-1.0.0.jar
itext-2.1.7.jar
odfdom-java-0.8.7.jar
org.odftoolkit.odfdom.converter-0.9.0.jar
org.odftoolkit.odfdom.converter.core-1.0.0.jar
org.odftoolkit.odfdom.converter.pdf-1.0.0.jar
org.odftoolkit.odfdom.converter.xhtml-1.0.0.jar
oro-2.0.8.jar
velocity-1.7.jar
</pre>
<p>Dont' forget an important security setting in <i>java.policy</i> file:</p>
<div id="_mcePaste"><i>grant {</i></div>
<div id="_mcePaste"><i><span> </span> permission java.lang.RuntimePermission "getClassLoader";</i></div>
<div id="_mcePaste"><i><span> </span> permission java.lang.RuntimePermission "setContextClassLoader";</i></div>
<div id="_mcePaste"><i>}</i></div>
<div><i><br /></i></div>
<div></div>
<div>After that, restart HTTP server.</div>
<div></div>
<h3>Server-side tools</h3>
<p>To manage the whole process I used an HTML page with a button that calls (via Ajax) an XPages, that deals with the fusion of the data (HTML string) in the template. At the end, I create the PDF file using <a class="external-link" href="http://itextpdf.com/">iText </a>libraries.</p>
<p>Related to XPages, it only call the servlet in the <i>afterPageLoad</i> event:</p>
<pre>com.redturtle.XDocReport.mergeAndPDF(
	facesContext.getExternalContext().getRequest(), 
	facesContext.getExternalContext().getResponse()
);
</pre>
<p>This is how it looks the package, which includes the servlet:</p>
<p><img alt="package" class="image-inline" src="http://blog.redturtle.it/uploads/copy_of_package.GIF" title="package" /></p>
<p>Finally, this is the servlet code:</p>
<pre>package com.redturtle;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.odftoolkit.odfdom.converter.pdf.PdfConverter;
import org.odftoolkit.odfdom.converter.pdf.PdfOptions;
import org.odftoolkit.odfdom.doc.OdfTextDocument;

import fr.opensagres.xdocreport.core.document.SyntaxKind;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;

import lotus.domino.NotesException;
import lotus.domino.Session;

public class XDocReport {

	private static String VERSION = "XDocReport Version 1.0.0";
	static PrintWriter outClass = null;
	private static Session session = null;

	public static void mergeAndPDF (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, InterruptedException, NotesException {

                // NO DIIOP
		session=DominoAccess.getCurrentSession();
		try {			
			// 1) Load ODT file by filling Velocity template engine
			InputStream in = new FileInputStream("/tmp/template.odt");

			IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in,TemplateEngineKind.Velocity);

			FieldsMetadata metadata = report.createFieldsMetadata();
			metadata.addFieldAsTextStyling("comments",SyntaxKind.Html,false);

			// 2) Create context Java model
			IContext context = report.createContext();
			context.put("comments", "&lt;b&gt;<strong>hello world&lt;/b&gt;</strong>");
			
			// 3) Generate report by merging Java model with the ODT
			OutputStream out = new FileOutputStream(new File("/tmp/ODTProjectWithVelocity_Out.odt"));
			report.process(context, out);

			// 1) Load ODT into ODFDOM OdfTextDocument 
			in= new FileInputStream(new File("/tmp/ODTProjectWithVelocity_Out.odt"));
			OdfTextDocument document = OdfTextDocument.loadDocument(in);

			// 2) Prepare Pdf options
			PdfOptions options = PdfOptions.create();
			
			// 3) Convert OdfTextDocument to PDF via IText
			out = new FileOutputStream(new  File("/tmp/ODTProjectWithVelocityList_Out.pdf"));
			PdfConverter.getInstance().convert(document, out, options);
 
                        // Only manage response to Ajax call
		        response.setContentType("text/plain");
		        response.setCharacterEncoding("UTF-8");
			outClass = new PrintWriter(response.getWriter());
			printAgent("OK");
			return;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected static void printAgent(String string) {
		outClass.println(string);
	}
}
</pre>
<p>Pay attention to these points:</p>
<ol>
<li><i>comments<strong> </strong>-<strong> </strong></i> variable name inside ODF template</li>
<li><i>metadata.addFieldAsTextStyling("comments",SyntaxKind.Html,false); - </i>fill variable with something in HTML syntax</li>
<li><i>&lt;b&gt;hello world&lt;/b&gt;</i> - HTML string to merge</li>
</ol>
<p><strong>NOTE:</strong><i> DominoAccess </i>and <i>JSFUtil</i> are two very helpful classes written by Karsten Lehmann: see the <a class="external-link" href="http://www.mindoo.com/web/blog.nsf/dx/18.07.2009191738KLENAL.htm?opendocument&amp;comments">full code</a>. Thanks to them, DIIOP process for communication is not required.</p>
<h3>Pro &amp; Cons.</h3>
<p>I think that it's a very powerful approach; the only limitation I've found is the restricted set of styles supported by the merge process (see <a class="external-link" href="http://code.google.com/p/xdocreport/wiki/ODTReportingJavaMainHTMLTextStyling#Supported_styles">there</a> for details). Feel free to make some test using this approach, and let me know what you think :-)</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Baglioni</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>Domino</dc:subject>
    
    
      <dc:subject>java</dc:subject>
    
    
      <dc:subject>xPages</dc:subject>
    
    <dc:date>2013-03-08T08:55:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/migrating-dexterity-items-to-dexterity-containers">
    <title>How to transform a dexterity Item in to a dexterity Container</title>
    <link>http://blog.redturtle.it/migrating-dexterity-items-to-dexterity-containers</link>
    <description>The use case of adding container capabilities to content types is common in the Plone world.
I show a nifty solution that applies to dexterity content types
</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<blockquote class="pullquote"><br />This is a rather technical post, full of code. Faint of hearth you are advised!</blockquote>
<h3>The story</h3>
<p>Not all the content types are designed from the beginning with a container behaviour, a feature that can become a requirement in consequence of specification changes.</p>
<p>It happened also to me and in my case I had to deal with dexterity based content types. I started googling around and found this <a class="external-link" href="https://groups.google.com/forum/?fromgroups=#!topic/dexterity-development/vI4lzGFhEig">unresolved question</a> on the dexterity mailing list.</p>
<p>Starting from the suggestions in the thread, I managed to find out a nifty solution that reveals some interesting aspects of the software we work with.</p>
<a name="anchor-breaktext"></a><div class="breakText">I will show you how to reproduce the problem and explain the solution I propose.</div>
<p class="breakText"> </p>
<h3>Creating the dexterity type</h3>
<p>First of all let's create through the web the <strong>Example content</strong> dexterity type:</p>
<p><img alt="Add Example content" class="image-inline" src="http://blog.redturtle.it/uploads/adddexteritycontent.png/@@images/4d2a064e-150c-41cc-8312-e2775d955f60.png" title="Add Example content" /></p>
<p>Then let's create the "<strong>Example 1</strong>" object:</p>
<p><img alt="Example 1 object" class="image-inline" src="http://blog.redturtle.it/uploads/example1view1.png/@@images/a6963282-ad2b-42db-a53a-2c1fcc611e30.png" title="Example 1 object" /></p>
<h3>Screwing it all up</h3>
<p>Going to the portal_type edit form we can make "<strong>Example content</strong>" become a folderish object by modifying it's content type class, just replace "Item" with "Container".</p>
<p><img class="image-inline" src="http://blog.redturtle.it/uploads/contenttypeclass.png" /></p>
<p>To make something interesting it is  probably advisable to play with the "<i>Filter content types?</i>" and "<i>Allowed content types</i>" properties, allowing the creation of objects inside this container.</p>
<p>Once this is done the newly created objects show a folderish behaviour and view:</p>
<p><img alt="Example 2 object" class="image-inline" src="http://blog.redturtle.it/uploads/example2view1.png/@@images/90dc5422-9ad8-4809-a654-eb8e10ee0799.png" title="Example 2 object" /></p>
<p>But the old one is completely <strong>unchanged</strong> and has to be migrated!</p>
<p>The objects have clearly a different nature, because they are instances of different classes. Going into a pdb we can clearly see it:</p>
<pre>(pdb) portal['example-1'].portal_type<br />'example_content'<br />(pdb) portal['example-2'].portal_type<br />'example_content'<br />(pdb) portal['example-1']<br />&lt;Item at /Plone/example-1&gt;<br />(pdb) portal['example-2']<br />&lt;Container at /Plone/example-2&gt;</pre>
<p>The portal type is the same but:</p>
<ol>
<li><strong>"Example 1"</strong> is an instance of <strong>plone.dexterity.content.Item</strong></li>
<li><strong>"Example 2"</strong> is an instance of <strong>plone.dexterity.content.Container.</strong></li>
</ol>
<h3>Building the box</h3>
<p>It is time to fold the paper sheet in to a box!</p>
<p><a class="external-link" href="https://groups.google.com/forum/#!msg/dexterity-development/vI4lzGFhEig/xj81brZ6MGAJ">Aspeli's suggestion</a> of replacing the __class__ attribute is a good starting point, but I found out that <strong>restarting the instance swallowed my changes</strong>.</p>
<p>I believe the answer can be found between the lines of <a class="external-link" href="http://tech.groups.yahoo.com/group/zope/message/158662">this post</a> from Dieter:</p>
<p class="callout"><i> The main problem [about __class__ switching] is that the <strong>class is usually coded</strong> (for efficiency reasons) <strong>in the persistent references to an object</strong>. As soon as the container is loaded from the ZODB, <strong>a ghost is created for its persistent reference using the class mentioned there</strong>.</i><br /> <i><br /> This means: it is <strong>not safe to change the class</strong> of a persistent object unless you although modify all its containers (otherwise, some persistent references remain with the old class. This potentially leads to non-deterministic behaviour).</i></p>
<p>A workaround that seems working to me is to detach the object from the ZODB, switch the class and put the object back in place, like shown in here:</p>
<pre>(pdb) obj = portal['example-1']<br />(pdb) del portal['example-1']<br />(pdb) obj<br />&lt;Item at /Plone/example-1&gt;<br />(pdb) from plone.dexterity.content import Container<br />(pdb) obj.__class__ = Container<br />(pdb) portal['example-1'] = obj</pre>
<p>This is unorthodox for sure, but for the time being it proved to be a working solution without side effects.</p>
<h3>Let's finish the job</h3>
<p>Ok, now the object is a <strong>Container instance</strong>!</p>
<pre>(pdb) obj<br />&lt;Container at /Plone/example-1&gt;</pre>
<p>But this is instance is not yet ready. As David Glick <a class="external-link" href="https://groups.google.com/d/msg/dexterity-development/vI4lzGFhEig/Ve2lKT6w8pcJ">suggests</a>:</p>
<p class="callout"><i><span style="text-align: start; float: none; "><span> </span>I doubt that [switching with the __class__] will be sufficient, since containers have internal data<span> </span></span><span style="text-align: start; float: none; ">structures that would <strong>need to get set up</strong> in order for the object to<span> </span></span><span style="text-align: start; float: none; ">function as a container.</span><span style="text-align: start; float: none; "> </span></i></p>
<p>Infact visiting "<strong>Example 1</strong>" returns an error:</p>
<pre>2013-02-20 16:03:23 ERROR Zope.SiteErrorLog 1361372603.770.0118314104451 http://localhost:8080/Plone/example-1<br />Traceback (innermost last):<br /> Module ZPublisher.Publish, line 115, in publish<br /> Module ZPublisher.BaseRequest, line 437, in traverse<br /> Module Products.CMFCore.DynamicType, line 147, in __before_publishing_traverse__<br /> Module Products.CMFDynamicViewFTI.fti, line 215, in queryMethodID<br /> Module Products.CMFDynamicViewFTI.fti, line 182, in defaultView<br /> Module Products.CMFPlone.PloneTool, line 847, in browserDefault<br /> Module Products.CMFPlone.PloneTool, line 715, in getDefaultPage<br /> Module Products.CMFPlone.utils, line 90, in getDefaultPage<br /> Module plone.app.layout.navigation.defaultpage, line 32, in getDefaultPage<br /> Module plone.app.layout.navigation.defaultpage, line 75, in getDefaultPage<br /> Module plone.folder.ordered, line 202, in __contains__<br />TypeError: argument of type 'NoneType' is not iterable</pre>
<p>Checking the code, it turns out that the <strong>_tree</strong> attribute of the instance is <strong>None</strong> as it can be verified with some analysis on the object:</p>
<pre>(pdb) obj._tree is None<br />True</pre>
<p>This is because we miss some initialization, so it's time to dive into Python and check which parent class __init__ function we have to call.</p>
<p>To understand this I analyzed the method resolution order of the two classes and tried to filtered out the parent classes that were not interesting for my sake, either because their __init__ is identical to object.__init__ or because they are in common with the Item class, and so their init method were already called during "<strong>Example 1</strong>" initialization.</p>
<p>A first attempt returns this:</p>
<pre>(pdb) container_mro = Container.__mro__<br />(pdb) item_mro = Item.__mro__<br />(pdb) container_only_klasses = [klass for klass in container_mro if not klass in item_mro and not klass.__init__ is object.__init__]<br />(pdb) pp container_only_klasses<br />[&lt;class 'plone.dexterity.content.Container'&gt;,<br /> &lt;class 'plone.folder.ordered.CMFOrderedBTreeFolderBase'&gt;,<br /> &lt;class 'plone.folder.ordered.OrderedBTreeFolderBase'&gt;,<br /> &lt;class 'Products.BTreeFolder2.BTreeFolder2.BTreeFolder2Base'&gt;,<br /> &lt;class 'Products.CMFCore.PortalFolder.PortalFolderBase'&gt;,<br /> &lt;class 'OFS.Folder.Folder'&gt;]</pre>
<p>This considerably lowers the __init__ that we want to check. But we can go further, by noting that at the end it is enough to call the CMFOrderedBTreeFolderBase __init__method:</p>
<pre>(pdb) from plone.folder.ordered import CMFOrderedBTreeFolderBase<br />(pdb) [klass for klass in container_only_klasses if not klass in CMFOrderedBTreeFolderBase.__mro__]<br />[&lt;class 'plone.dexterity.content.Container'&gt;]</pre>
<p>Asking help on this class __init__ reveals:</p>
<pre>(pdb) !help(CMFOrderedBTreeFolderBase.__init__)<br />Help on method __init__ in module plone.folder.ordered:<br /><br />__init__(self, id, title='') unbound plone.folder.ordered.CMFOrderedBTreeFolderBase method</pre>
<p>So to properly set up the missing blocks we just want to call this class __init__ passing as arguments the object itself, its id and its title:</p>
<pre>(pdb) CMFOrderedBTreeFolderBase.__init__(obj, obj.getId(), obj.title)</pre>
<p>Great, a new tree has born!</p>
<pre>(pdb) obj._tree._tree
&lt;BTrees.OOBTree.OOBTree object at 0xb4a85f5c&gt;</pre>
<p>To finalize our work the object has to be reindexed and the transaction committed:</p>
<pre>(pdb) obj.reindexObject()<br />(pdb) from transaction import commit<br />(pdb) commit()</pre>
<h3>Final remarks</h3>
<p>Of course code like this is intended for an upgrade step!</p>
<p>The techniques described in this post are for sure interesting and powerful, but I would not rely on such low level tricks for routine operations, i.e. they are useful for doing migration or management scripts but <strong>definitely not suited for a browser view</strong>!</p>
<p>My use case was slightly different and more complicated: I was working with classes derived from the dexterity Item and Content classes, but I simplified it for making an already complex topic clearer.</p>
<p>If you have a more complicated case, <strong>further actions</strong> may be needed to complete properly this migration. In my case, for example, I also had to change the portal_type and remap some attributes.</p>
<div>I do not see any reason why the same methodology should fail with other kind of objects, Archetypes for examples.</div>
<p> </p>
<p>Many times I read about the suggestion of <strong>creating content types that are folderish even if not requested by the specification</strong>. As you can see this choice allows more flexibility and can save you from the need of writing migration scripts or upgrade steps at a later time.</p>
<h3>Credits</h3>
<p><span><a href="http://teach.alimomeni.net/2012fall2b/wp-content/uploads/2012/10/origami-box.jpg">Original image </a></span>adapted by <a class="external-link" href="https://twitter.com/@petraplatz">@petraplatz</a></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Alessandro Pisa</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>python</dc:subject>
    
    
      <dc:subject>Dexterity</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>tutorials</dc:subject>
    
    <dc:date>2013-02-25T13:05:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/caution-2013-meteor-will-hit-the-world-wide-web">
    <title>Caution: in 2013 a "Meteor" will impact the World (Wide Web)</title>
    <link>http://blog.redturtle.it/caution-2013-meteor-will-hit-the-world-wide-web</link>
    <description>Meteor is a very powerful Javascript framework: this short article demonstrate how to install, configure and create your first application using "Meteor"</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Nothing to do with the Mayan prophecies, quiet!</p>
<p>Some time ago I came across a tweet that talked about <a class="external-link" href="http://meteor.com/">Meteor</a> and, as usual, I tried to investigate the simple reading.</p>
<div></div>
<div id="_mcePaste">I knew of the potential offered by Node.JS but I never tried something, so I took the opportunity to understand more. Also, these types of frameworks are increasingly directing a new way to write web applications (interesting this <a class="external-link" href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/">article</a>). Furthermore, <a class="external-link" href="http://madewith.meteor.com/">here</a> you can find a lot of examples of application made with Meteor.</div>
<blockquote class="pullquote">Meteor runs on Node.js. Has it's own server</blockquote>
<div></div>
<div></div>
<div id="_mcePaste"></div>
<div id="_mcePaste">Without spending a lot of time, I will try to reproduce steps how to create from scratch the environment and a simple application.</div>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p> </p>
<p>First, install Meteor downloading the <a class="external-link" href="http://win.meteor.com/">installer</a> (in my case, on an old Windows XP machine - yes, there is also for Windows!).</p>
<p>Completed the first step, go to the installation folder of Meteor and create the application.</p>
<p><img src="http://blog.redturtle.it/uploads/copy_of_1.GIF" alt="setup&amp;config" class="image-inline" title="setup&amp;config" /></p>
<p>Now, let's create pages, css and javascript files. Basically, file are structured in three folders:</p>
<ul>
<li>client</li>
<li>server</li>
<li>public.</li>
</ul>
<blockquote class="pullquote">Meteor uses MongoDB, through Javascript API called <a class="external-link" href="http://docs.meteor.com/#meteor_collection">"collection"</a></blockquote>
<p>All files in client directory are served only to clients (server doesn't know about them), files in public are resources most of the time, i.e. images. Server directory serves data to server. Everything outside those folders is shared between clients and server (it would be a good place to put scripts or templates to run on both, server and client, more about that other time). In our simple program we are going to use only client directory.</p>
<p>helloworld.css</p>
<pre>html {margin:0;background-color: #eee;}

body {
width: 640px;
margin:auto;
text-align: center;
font-family: 'Helvetica';
color: #aaa;
text-shadow:1px 1px #fff;
}

p {font-style: italic}
</pre>
<p>helloworld.html</p>
<pre>&lt;head&gt;
 &lt;title&gt;Hello World&lt;/title&gt;
&lt;/head&gt;
 
&lt;body&gt;
&lt;h1&gt;Hello&lt;/h1&gt;
&lt;p&gt;My very first application&lt;/p&gt;
&lt;div style="float:left;width:49%;text-align:left"&gt;{{&gt; hello}}&lt;/div&gt;
&lt;div style="float:right;width:50%;text-align:left"&gt; 
{{&gt; form}}&lt;br&gt;&lt;br&gt;
{{&gt; anotherform}}
&lt;/div&gt;
&lt;/body&gt;
 
&lt;template name="hello"&gt;
 {{somebody}}
&lt;/template&gt;
 
&lt;template name="form"&gt;
&lt;input id='newName' type='text'/&gt;&lt;input type='submit' value='Set!'/&gt;
&lt;/template&gt;

&lt;template name="anotherform"&gt;
 &lt;input id='newNameAppend' type='text'/&gt;&lt;input type='submit' value='Append!'/&gt;
&lt;/template&gt;

</pre>
<p>helloworld.js</p>
<pre>Session.set( 'somebody' , '' );
 
Template.hello.somebody = function(){
    return Session.get('somebody');
}
 
Template.form.events({
     'click input[type=submit]': function(){
     Session.set( 'somebody' , $('#newName').val() );
}
 
});

Template.anotherform.events({
     'click input[type=submit]': function(){
     Session.set( 'somebody' , Session.get( 'somebody') +'\n'+ $('#newNameAppend').val() );
}
 
});
</pre>
<p><br /> css file is trivial, the most important things are about html and js file.</p>
<p>Let's get straight to the .html, that could be put there whatever you would like to render. Just without links to CSS and/or other scripts. If needed to include something, just copy file inside file structure (client, server, public or root of your project) and Meteor will minify it and include along other files.</p>
<p>Furthermore, html is written in <a class="external-link" href="http://handlebarsjs.com/">Handlebars</a> syntax, a powerful templates for javascript.</p>
<p>Inside curly brackets you put names of variables (<strong>somebody</strong>) or templates (<strong>&gt; hello</strong>). "&gt;" sign means that you are including a template. In our case we are including <strong>hello, form</strong> and <strong>anotherform</strong> templates which definitions you can find between template tags.</p>
<p>Let's talk about .js: In <strong>helloworld.js</strong> we set up a default value (void) for our session variable</p>
<pre>Session.set( 'somebody' , '' );</pre>
<p>Now that we have a variable inside a session, our template can use it to display</p>
<pre>Template.hello.somebody = function(){
return Session.get('somebody');
}</pre>
<p>All templates you setup are available in a namespace <strong>Template</strong>. In this case we have <i>Template.hello, Template.form</i> and <i>Template.anotherform</i> already defined for us by Meteor. To use {{somebody}} in the template, we must define that variable to get a proper display. We make it a simple function that returns our session value with <strong>Session.get('somebody')</strong>.</p>
<p>Finally, let's talk about <i>onclick events</i>:</p>
<pre>Template.form.events({
 'click input[type=submit]': function(){
 Session.set( 'somebody' , $('#newName').val() );
 }
});</pre>
<pre>Template.anotherform.events({
     'click input[type=submit]': function(){
     Session.set( 'somebody' , Session.get( 'somebody') +'\n'+ $('#newNameAppend').val() );
}
});
</pre>
<p>Using Template namespace we are reaching <strong>form </strong>and <strong>anotherform </strong>template. The first sets and displays the value submitted in text field, the second appends to present values just submitted. To handle events we put an object with definition inside an event function.</p>
<pre>Template.form.events( {} );
</pre>
<p><br /> That's it! Notice that each time we edit a file, no reload of our page is needed: it's automatically updated "on-the-fly".</p>
<p>This is a screenshot of the whole application, very simple but, IMHO, very clear. Stay tuned for something more complex about Meteor application in next posts.</p>
<p><img src="http://blog.redturtle.it/uploads/copy_of_example.GIF" alt="example" class="image-inline" title="example" /></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Baglioni</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Node.js</dc:subject>
    
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>javascript</dc:subject>
    
    
      <dc:subject>web</dc:subject>
    
    <dc:date>2013-01-30T09:15:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/buildout-plone-vs-forefront-tmg-using-cntlm">
    <title>Break free from forefront TMG proxy</title>
    <link>http://blog.redturtle.it/buildout-plone-vs-forefront-tmg-using-cntlm</link>
    <description>I was asked to install and configure a debian server to run a Plone site behind Microsoft Forefront TMG. Mission impossible? No... just a story to tell!</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<blockquote class="pullquote">It was a dark and stormy night, me and the server, Loca, left all alone in a chilly room.</blockquote>
<p>To let a linux server connect with <strong>Forefront</strong> I wanted to set up and run <a class="external-link" href="http://cntlm.sourceforge.net/">cntlm</a>, which is a local proxy that authenticates to a Forefront gateway to  allow internet traffic.</p>
<a name="anchor-breaktext"></a><div class="breakText">I had to install it manually on a debian server after that a minimal installation with the <a class="external-link" href="http://www.debian.org/CD/netinst/">netinst cd</a> was aborted.</div>
<p>The server was offline, I had to think about an <strong>offline method</strong> to install cntlm. I downloaded the deb from <a class="external-link" href="http://ftp.debian.org/pool/main/c/cntlm/cntlm_0.35.1-5_i386.deb">http://ftp.debian.org/pool/main/c/cntlm/cntlm_0.35.1-5_i386.deb</a> and saved it on a USB pen drive, then installed the deb with dpkg:</p>
<pre>dpkg - i cntlm_0.35.1-5_i386.deb
</pre>
<p>Once I got cntlm installed I tested my Forefront connection parameters using the <i>"magic"</i> <strong>-M</strong> flag:</p>
<pre>cntlm -fv -l $PORT -u $USER@$DOMAIN -p $PASSWORD \
      -w $NETBIOS_NAME -M $URL $TGMIP $TGMPORT
</pre>
<p>This will gave me hints to edit /etc/cntlm.conf file properly in order to run cntlm in daemon mode.</p>
<blockquote class="pullquote">I had just a debian network install cd with me and I asked Loca if she wanted some.</blockquote>
<p>A short explanation of the arguments in the command line follows:</p>
<ul>
<span class="discreet"> </span>
<li><span class="discreet"><strong> -fv</strong> run cntlm in foreground and verbose mode</span></li>
<span class="discreet"> </span>
<li><span class="discreet"> <strong>-l $PORT</strong> listen to the specified port (default 3128)</span></li>
<span class="discreet"> </span>
<li><span class="discreet"> <strong>-p $PASSWORD</strong> you should know it...</span></li>
<span class="discreet"> </span>
<li><span class="discreet"> <strong>-u $USER@$DOMAIN</strong> the user that authenticates to Forefront (e.g. alert@redturtle)</span></li>
<span class="discreet"> </span>
<li><span class="discreet"> <strong>-w $NETBIOS_NAME</strong> </span><span class="discreet">the w</span>orkstation NetBIOS name<span class="discreet"> (</span><span class="discreet">e.g. REDTURTLE)</span></li>
<span class="discreet"> </span>
<li><span class="discreet"> <strong>-M $URL</strong> probe a test url to make "magic detection" (e.g. http://www.example.org)</span></li>
<span class="discreet"> </span>
<li><span class="discreet"> <strong>$TGMIP</strong> the Forefront gateway ip address (e.g. 10.0.0.10)</span></li>
<span class="discreet"> </span>
<li><span class="discreet"> <strong>$TGMPORT</strong> the port Forefront gateway is listening to (e.g. 8080)</span></li>
</ul>
<p>More information on the cntlm man page (check out the <a class="external-link" href="http://man.devl.cz/man/1/cntlm">online version</a>).</p>
<h3>Environment variables</h3>
<p>With cntlm up and running daemonized by the init scripts, to use the proxy I had to define the proper environment variables:</p>
<pre>export http_proxy=http://127.0.0.1:3128
export https_proxy=http://127.0.0.1:3128
export ftp_proxy=http://127.0.0.1:3128 </pre>
<h3>apt</h3>
<p>I had also to setup apt, adding a file /etc/apt/apt.conf.d/02proxy containing those lines:</p>
<pre>Acquire::http::proxy "http://localhost:3128/";
Acquire::ftp::proxy "ftp://localhost:3128/";
Acquire::https::proxy "https://localhost:3128/";
</pre>
<p><span class="discreet">Source: <a class="external-link" href="http://askubuntu.com/questions/89437/how-to-install-packages-with-apt-get-on-a-system-connected-via-proxy">http://askubuntu.com/questions/89437/how-to-install-packages-with-apt-get-on-a-system-connected-via-proxy</a></span></p>
<h3>Subversion</h3>
<p>To use svn for checkouts I had to look in /etc/subversion/servers  for the "[Global]" section and added  a couple of lines like in this example:</p>
<pre>[Global]
...
http-proxy-host=localhost
http-proxy-port=3128
... </pre>
<p><span class="discreet"> Source: <a class="external-link" href="http://stackoverflow.com/questions/82530/svn-over-http-proxy">http://stackoverflow.com/questions/82530/svn-over-http-proxy</a></span></p>
<h3>Buildout</h3>
<blockquote class="pullquote">After a few moments we were friends and decided to join our efforts from freedom.</blockquote>
<p>Once I apt-got all the packages I needed and checked out my Plone buildout I thought everything would be fine.<br /><br /><strong><i>Of course I was wrong!</i></strong><br />There's an issue, apparently with urllib, that makes buildout fail (see <a class="external-link" href="https://bugs.launchpad.net/zc.buildout/+bug/484735">https://bugs.launchpad.net/zc.buildout/+bug/484735</a>, <a class="external-link" href="https://github.com/buildout/buildout/issues/32">https://github.com/buildout/buildout/issues/32</a>).</p>
<p>I forked buildout on github to work around this issue.</p>
<p>You can clone  <a class="external-link" href="https://github.com/ale-rt/buildout/tree/issue-32">https://github.com/ale-rt/buildout/tree/issue-32</a> and can get the source tarball from <a class="external-link" href="https://github.com/downloads/ale-rt/buildout/zc.buildout-1.6.4-issue-32-1.tar.gz">https://github.com/downloads/ale-rt/buildout/zc.buildout-1.6.4-issue-32-1.tar.gz</a>.</p>
<p>To use it I suggest you to create a virtual env in your buildout directory, add in the buildout root a folder (e.g. pypi-local), download to that folder the tarball and "pip install" it, the commands are something like:</p>
<pre>virtualenv cntlm<br />cd cntlm/<br />. bin/activate<br />mkdir pypi-local<br />cd pypi-local/<br />wget https://github.com/downloads/ale-rt/buildout/zc.buildout-1.6.4-issue-32-1.tar.gz<br />cd ..<br />./bin/pip install pypi-local/zc.buildout-1.6.4-issue-32-1.tar.gz </pre>
<p>To use this folder as a <strong>local pypi repository</strong> in your buildout, edit your buildout configuration file and add to the <strong>find-links</strong> this folder. Don't forget to pin the zc.buildout version!</p>
<pre>[buildout]<br />...<br />find-links = <br />    ...<br />    file://${buildout:directory}/pypi-local<br />    ...<br /><br />[versions]<br />...<br />zc.buildout = 1.6.4-issue-32-1</pre>
<p>With this setup buildout runs fine :)!</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Alessandro Pisa</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>buildout</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2013-01-17T15:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/how-to-write-custom-plugin-for-nagios-and-check_mk">
    <title>A custom port scanner plugin for Nagios and Check_mk</title>
    <link>http://blog.redturtle.it/how-to-write-custom-plugin-for-nagios-and-check_mk</link>
    <description>“I can't believe how dark was the time without a monitoring system...”. This is what my boss told me last time we spoke about reliability of service</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Some months ago I <a class="external-link" href="http://blog.redturtle.it/plone-e-i-sistemi-di-monitoraggio">posted</a> (Italian only) about <a class="external-link" href="http://http//mathias-kettner.de/check_mk.html">Check_mk</a> as a monitoring tool which can be used also to taking care of Plone instances. This time I will post a small custom plugin I wrote for <a class="external-link" href="http://www.nagios.org">Nagios</a>.</p>
<h3>Check_mk scan_port plugin<img alt="code" class="image-right" src="http://blog.redturtle.it/uploads/code.jpg" title="code" /></h3>
<p> </p>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText">I was looking for a way (a plugin) to test some specific ports on my servers within the local network. Surfing the net I found many scripts that do almost what I wanted (especially one written in Perl as <a class="external-link" href="http://nmap.org/">nmap</a> wrapper) but despite of all I decide to write my own.</div>
<p>The reason of this choice is because most of them make use of system tools in order to perform port scan action. There is no problem with that, tools like <strong>nmap</strong> are really commons, but what I want is avoid any kind of dependence.</p>
<p>Moreover I prefer have control on the code since the beginning mainly because I can choose the programming language ;)</p>
<h3>The code</h3>
<p>Check_port plugin is written in <a class="external-link" href="http://www.python.org">Python</a> and it uses only the standard library thus it should be portable as long as you have Python installed on your system.</p>
<p>The code is quite simple, for each given port the program test if the connection is active.</p>
<div><strong>Note: </strong><i>This test tells you if something is listening but nothing more.</i></div>
<div><i><br /></i></div>
<div>Source: <a class="external-link" href="https://github.com/nicolasenno/check_mk_plugins/tree/master/check_ports">github repository</a></div>
<h3>Usage</h3>
<div>Plugin accepts 3 arguments:</div>
<div>
<ul>
<li>-o &lt;ip&gt;  : remote host to scan</li>
<li>-p &lt;ports&gt;   : list of ports to scan</li>
<li>-t &lt;timeout&gt;] (optional)</li>
</ul>
</div>
<div><br />Example from command line:</div>
<pre># Scan for port 22 and 25 on a remote server 192.168.1.100<br />./check_ports.py -o 192.168.1.100 -p 22,25
</pre>
<div>Only two return states are allowed:</div>
<div>
<ul>
<li>OK: All the given ports are opened</li>
<li>CRITICAL: At list one of the given port is closed</li>
</ul>
</div>
<div>State: <strong>OK</strong></div>
<pre>./check_ports.py -o 188.165.195.56 -p 22<br />OK; opened 22 ; closed</pre>
<div>State <strong>CRITICAL</strong></div>
<pre>./check_ports.py -o 188.165.195.56 -p 23<br />CRITICAL; opened  ; closed 23</pre>
<h3></h3>
<h3>Check_mk configuration</h3>
<div>The easier way to configure the plugin is define a command as legacy check, and</div>
<div><strong>Check_mk </strong>will do the rest:</div>
<pre># 'check_ports'<br />define command{<br />  command_name check_ports<br />  command_line $USER1$/check_ports.py -o $ARG1$ -p $ARG2$ <br />}</pre>
<div>Then you can specify a list of remote server to test as show below:</div>
<pre>(( "Check_ports!127.0.0.1!22,23", "Check ports", False), ['host'])</pre>
<p><strong>Note:</strong> <i>be sure you are not blocked by a firewall.</i></p>
<div></div>
<div>At the moment this plugin accepts only a list of ports, maybe in future will be possible to use also a range.</div>
<div></div>
<div></div>
<div>If you need more information on how to use <i>lagacy plugin</i> in <strong>Check_mk</strong> you can find some resource <a class="external-link" href="http://mathias-kettner.de/checkmk_legacy_checks.html">here</a>.</div>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Nicola Senno</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>Networking</dc:subject>
    
    
      <dc:subject>Monitoring</dc:subject>
    
    
      <dc:subject>integration</dc:subject>
    
    <dc:date>2013-01-11T10:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/lotus-domino-twitter-way-for-mobile-approach">
    <title>Mixing Lotus Domino and Twitter together - a way for mobile approach</title>
    <link>http://blog.redturtle.it/lotus-domino-twitter-way-for-mobile-approach</link>
    <description>What if you want to create different layouts for different devices in Lotus Domino? This is a way to make this possible, for example using Twitter Bootstrap </description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>It's always more important to develop applications that are accessible from any device so we wondered what it takes to adapt an application, perhaps already developed, to ensure this possibility. In this case, Twitter provides its layout via <a class="external-link" href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>, so it was decided to integrate it.</p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<div id="_mcePaste">Twitter Bootstrap requires the HTML 5 doctype as you can see in the <a class="external-link" href="http://twitter.github.com/bootstrap/scaffolding.html#global">documentation</a>.</div>
<div>Since version 8.5.3 Lotus Domino allows to define, for the XPages, this kind of doctype, in this way:</div>
<div><br /><img src="http://blog.redturtle.it/uploads/copy_of_doctype.PNG" alt="doctype" class="image-inline" title="doctype" /></div>
<p>Next step: we imported the resources you need to Twitter Bootstrap within the Domino project:</p>
<p><img src="http://blog.redturtle.it/uploads/copy_of_resources.png" alt="resources" class="image-inline" title="resources" /></p>
<p>And finally, we have created an XPages with the following source code:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xp:view xmlns:xp="http://www.ibm.com/xsp/core"&gt;
    &lt;xp:this.resources&gt;
       &lt;xp:styleSheet href="bootstrap.css"&gt;&lt;/xp:styleSheet&gt;
       &lt;xp:styleSheet href="bootstrap-responsive.css"&gt;&lt;/xp:styleSheet&gt;
       &lt;xp:metaData name="viewport" content="width=device-width, initial-scale=1.0"&gt;
       &lt;/xp:metaData&gt;
    &lt;/xp:this.resources&gt;
    &lt;!-- NAVIGATION BAR --&gt;
    &lt;br/&gt;&lt;br/&gt;
  &lt;xp:panel styleClass="navbar navbar-inverse navbar-fixed-top"&gt;
    &lt;xp:panel styleClass="navbar-inner"&gt;
    &lt;xp:panel styleClass="container"&gt;
    &lt;xp:panel styleClass="row"&gt;
    &lt;xp:panel styleClass="span4"&gt;
      &lt;xp:label id="label1"&gt;
        &lt;xp:this.value&gt;&lt;![CDATA[#{javascript:"Welcome " + @Name("[CN]",@UserName())}]]&gt;&lt;/xp:this.value&gt;
      &lt;/xp:label&gt;
    &lt;/xp:panel&gt;
    &lt;xp:panel styleClass="span6"&gt;
      &lt;ul class="nav nav-pills"&gt;
       &lt;li class="dropdown"&gt;
         &lt;a class="dropdown-toggle" data-toggle="dropdown" href="#"&gt;
           &lt;i class="icon-white icon-file"&gt;&lt;/i&gt; Dropdown &lt;b class="caret"&gt;&lt;/b&gt;
         &lt;/a&gt;
         &lt;ul class="dropdown-menu"&gt;
           &lt;li&gt;&lt;a tabindex="-1" href="#"&gt;Action&lt;/a&gt;&lt;/li&gt;
           &lt;li&gt;&lt;a tabindex="-1" href="#"&gt;Another action&lt;/a&gt;&lt;/li&gt;
           &lt;li&gt;&lt;a tabindex="-1" href="#"&gt;Something else here&lt;/a&gt;&lt;/li&gt;
           &lt;li class="divider"&gt;&lt;/li&gt;
           &lt;li&gt;&lt;a tabindex="-1" href="#"&gt;Separated link&lt;/a&gt;&lt;/li&gt;
         &lt;/ul&gt;
      &lt;/li&gt;
     &lt;/ul&gt;
    &lt;/xp:panel&gt;
    &lt;xp:panel styleClass="span2"&gt;
      &lt;xp:label value="Logout" id="label3"&gt;&lt;/xp:label&gt;
    &lt;/xp:panel&gt;
   &lt;/xp:panel&gt;
  &lt;/xp:panel&gt;
 &lt;/xp:panel&gt;
 &lt;/xp:panel&gt;
 &lt;!-- APPLICATION LAYOUT --&gt;
 &lt;xp:panel styleClass="subhead"&gt;
   &lt;xp:panel styleClass="container"&gt;
     &lt;xp:panel styleClass="row"&gt;
       &lt;xp:panel styleClass="span4"&gt;
        &lt;ul class="nav nav-list sidebar-nav-fixed"&gt;
          &lt;li class="nav-header"&gt;List header&lt;/li&gt;
          &lt;li class="active"&gt;&lt;a href="#"&gt;&lt;i class="icon-white icon-home"&gt;&lt;/i&gt;Home&lt;/a&gt;
          &lt;/li&gt;
          &lt;li&gt;&lt;a href="#"&gt;&lt;i class="icon-book"&gt;&lt;/i&gt;Library&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="#"&gt;&lt;i class="icon-pencil"&gt;&lt;/i&gt;Applications&lt;/a&gt;&lt;/li&gt;
          &lt;li class="nav-header"&gt;Another list header&lt;/li&gt;
          &lt;li&gt;&lt;a href="#"&gt;&lt;i class="icon-user"&gt;&lt;/i&gt;Profile&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="#"&gt;&lt;i class="icon-cog"&gt;&lt;/i&gt;Settings&lt;/a&gt;&lt;/li&gt;
          &lt;li class="divider"&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="#"&gt;&lt;i class="icon-flag"&gt;&lt;/i&gt;Help&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
       &lt;/xp:panel&gt;&lt;br/&gt;
       &lt;xp:panel styleClass="span8"&gt;
         &lt;xp:table&gt;
           &lt;xp:tr&gt;
            &lt;xp:td&gt;&lt;xp:label value="First Name" id="label2"&gt;&lt;/xp:label&gt;&lt;/xp:td&gt;
            &lt;xp:td&gt;&lt;xp:inputText id="inputText1"&gt;&lt;/xp:inputText&gt;&lt;/xp:td&gt;
           &lt;/xp:tr&gt;
           &lt;xp:tr&gt;
            &lt;xp:td&gt;&lt;xp:label value="Last Name" id="label4"&gt;&lt;/xp:label&gt;&lt;/xp:td&gt;
            &lt;xp:td&gt;&lt;xp:inputText id="inputText2"&gt;&lt;/xp:inputText&gt;&lt;/xp:td&gt;
           &lt;/xp:tr&gt;
           &lt;xp:tr&gt;
            &lt;xp:td&gt;&lt;xp:label value="Address" id="label5"&gt;&lt;/xp:label&gt;&lt;/xp:td&gt;
            &lt;xp:td&gt;&lt;xp:inputTextarea id="inputTextarea1"&gt;&lt;/xp:inputTextarea&gt;&lt;/xp:td&gt;
           &lt;/xp:tr&gt;
           &lt;xp:tr&gt;
            &lt;xp:td&gt;&lt;xp:label value="Phone" id="label6"&gt;&lt;/xp:label&gt;&lt;/xp:td&gt;
            &lt;xp:td&gt;&lt;xp:inputText id="inputText3"&gt;&lt;/xp:inputText&gt;&lt;/xp:td&gt;
           &lt;/xp:tr&gt;
         &lt;/xp:table&gt;
       &lt;/xp:panel&gt;
      &lt;/xp:panel&gt;
     &lt;/xp:panel&gt;
    &lt;/xp:panel&gt;
  &lt;script type="text/javascript" src="js/jQuery-1.8.0.min.js" clientSide="true"&gt;&lt;/script&gt;
  &lt;script type="text/javascript" src="js/bootstrap.js" clientSide="true"&gt;&lt;/script&gt;
&lt;/xp:view&gt;</pre>
<p><br /> This is what you get on the page number from the web:<img src="http://blog.redturtle.it/uploads/copy4_of_preview.PNG" alt="preview" class="image-inline" title="preview" /><br />Of course, nothing prevents you from using any other responsive layout: Twitter is only one of the choices!</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Baglioni</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Lotus</dc:subject>
    
    
      <dc:subject>Domino</dc:subject>
    
    
      <dc:subject>HTML5</dc:subject>
    
    
      <dc:subject>xPages</dc:subject>
    
    <dc:date>2012-11-28T15:20:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/angel-of-arnhem">
    <title>Angel of Arnhem</title>
    <link>http://blog.redturtle.it/angel-of-arnhem</link>
    <description>My first Plone conference is over and it was great! I boldly decided to present a talk and survived to this adventure. That's the story, morning glory!
</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>A month passed since the <strong>Plone conference</strong> in <strong>Arnhem</strong> and a lot of posts hit the blogosphere announcing to the world  the technical progresses of our beloved <strong>CMS</strong>.</p>
<p>Being that I am missing so much the moments shared in that wonderful city with the people I met at the conference, I decided to write a post not about the software, but about our amazing  <strong>community</strong> and how I had fun and in presenting my talk at the conference.</p>
<p>During the summer I felt myself a bit daring   by submitting a talk to the conference, but I was not caring so much... I was quite confident it would not be accepted!<strong> </strong></p>
<p><strong>Instead</strong> I had the first surprise: not only my talk was accepted but I even had much more positive feedback than expected!</p>
<p><strong>Wow!</strong> I was gifted with the opportunity to share my experience on the Plone stage!</p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p>The conference offers four parallel tracks, and when I knew that my talk was scheduled simultaneously with the ones by rockstars as <strong>Martin Aspeli</strong>, <strong>Steve McMahon</strong> and (most of all) <strong>Simone <i>Simahawk</i> Orsi</strong>, I was quite sure my destiny was to give a presentation to an <strong>empty</strong> room.</p>

<p>The morning of the conference I was at the same time scared and excited, but than something happened... When I went to the stage I was told to wait for people getting into the room.</p>
<p>I told to the few people there: <i>"Come on! The rockstars are playing around, I do not think anybody else is gonna come!"</i> and then started talking with my audience and discovered they were very friendly. This calmed me down and made me understand that I was not a stranger in strange land!</p>
<p>Then, suddenly, the chair told me to start and I realized the room was full of people, when did they arrive?! I was <strong>galvanized</strong>, I pushed the button and started my presentation and fell in to trance.</p>
<p>Can't tell you the story of how I did arrive to the <i>"Questions?"</i> slide, <i>of course</i> <a class="external-link" href="http://www.youtube.com/watch?v=l1hPnW-qp6c">there is a video on youtube</a> , but it happened and, listen everybody, <strong>nobody bit me</strong>!</p>
<p>So, young (and old)  Plonistas that are afraid to submit a talk, be brave! You will find lots of people that are enthusistically waiting for you to share your experience and thoughts in the next <strong>Plone conference</strong> I bet you can do a great job and you will love <strong>Plone</strong> even more once you will touch with hand that a great part of <strong>Plone</strong> power comes from <strong>Plone</strong> people!</p>
<p style="text-align: center; "><strong><i>So... keep calm and Plone Conference 2013 in Brazil!</i></strong></p>
<p style="text-align: center; "><img src="http://blog.redturtle.it/uploads/kcapib2013.jpg/@@images/1ddb8589-f337-4220-8603-cf413944eefa.jpeg" alt="" class="image-inline" title="" /></p>
<h3>Credits</h3>
<p>I would really like to thank <strong>Irene</strong>, <strong>Andrew</strong>, <strong>Massimo</strong> and <strong>Stefano</strong> and the <strong>never-too-much-thanked</strong> guys from <strong><a class="external-link" href="http://www.fourdigits.nl/">Four digits</a></strong>!</p>
<p>Lead image taken from <a class="external-link" href="http://www.flickr.com/photos/maartenbos/3875719428/sizes/l/in/set-72157622198237540/">Maarten Bos' photostream</a></p>
<h3>Links</h3>
<ol>
<li><a class="external-link" href="http://www.youtube.com/watch?v=l1hPnW-qp6c">The video of my presentation</a></li>
<li><a class="external-link" href="http://www.slideshare.net/alepisa/lets-ecommerce-together-and-feel-plone-right">My Presentation on slide share</a></li>
</ol>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Alessandro Pisa</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>conference</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>community</dc:subject>
    
    
      <dc:subject>eventi</dc:subject>
    
    <dc:date>2012-11-13T10:40:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/how-to-integrate-d3-graphic-library-in-lotus-domino-environment">
    <title>How to integrate D3 graphic library in Lotus Domino environment</title>
    <link>http://blog.redturtle.it/how-to-integrate-d3-graphic-library-in-lotus-domino-environment</link>
    <description>A simple example of how to easily integrate graphics library D3 in Lotus Domino, and generate interactive charts based on the data exposed by a view of a XPages</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>During <strong>Better Software</strong> (<a class="external-link" href="http://www.bettersoftware.it/">http://www.bettersoftware.it/</a>) held in September in Florence, I attended many interesting talks, including one held by Luca Mearelli (the link to the presentation is available at <a class="external-link" href="http://spazidigitali.com/d3js_at_bsw12/">http://spazidigitali.com/d3js_at_bsw12/</a>) which dealt with the graphics library Javascript <strong>D3</strong> (<a class="external-link" href="http://d3js.org/">http://d3js.org/</a>)</p>
<blockquote class="pullquote" id="_mcePaste">This is just a brief example of how to integrate D3 into a framework (Lotus Domino is what I use), but there is nothing that we can do the same thing anywhere else.</blockquote>
<div></div>
<div>I thought it was interesting to understand how you can integrate this library in a Lotus Domino XPages, in particular for manipulating data exposed by views, forms, and more.</div>
<p> </p>
<p><strong>D3.js</strong> is a JavaScript library for manipulating documents based on data. <strong>D3</strong> helps you bring data to life using HTML, SVG and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.</p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p>This is an interesting interpretation of Chris Viau: <i>"D3 is not an SVG layer, not a compatibility layer and especially not an abstraction layer. It's a set of tools on top of web technologies to bind data elements to DOM".</i></p>
<h3><i>Technical requirements</i></h3>
<p>D3 expose the full capabilities of web standards such as <strong>CSS3</strong>, <strong>HTML5 </strong>and <strong>SVG</strong>. With minimal overhead, D3 is extremely fast, supporting large datasets and dynamic behaviors for interaction and animation. D3’s functional style allows code reuse through a diverse collection of <a class="external-link" href="https://github.com/mbostock/d3/wiki/API-Reference">components</a> and <a class="external-link" href="https://github.com/d3/d3-plugins">plugins</a>.</p>
<h3>An example of integration in Lotus Domino</h3>
<p>In this example, we integrate D3 in XPages containing a view that displays numeric data, and see how we can process it in a graph directly using the DOM of the page.</p>
<p>First of all, it is necessary to integrate D3 library and CSS file in XPages:</p>
<p><img src="http://blog.redturtle.it/uploads/cssjs.JPG" alt="css&amp;js resources" class="image-inline" title="css&amp;js resources" /></p>
<p>This is CSS file:</p>
<pre>path {
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}
 
line {
    stroke: black;
}
 
text {
    font-family: Arial;
    font-size: 9pt;
}</pre>
<p>Let's take a look at XPages view:</p>
<p><img src="http://blog.redturtle.it/uploads/copy3_of_Button.JPG" alt="view" class="image-inline" title="view" /></p>
<p>As you can see, I built a button to generate the graph based on the data in the second column of the view, this is the JS code:</p>
<pre>get_tags = document.getElementsByClassName('values');
var datasets = []; 
for(var i = 0; i &lt; get_tags.length; i++) {
	 datasets = datasets.concat(parseInt(get_tags[i].firstChild.innerHTML));
	 
}
    
var data = datasets,
w = 400,
h = 200,
margin = 30,
y = d3.scale.linear().domain([0, d3.max(data)]).range([0 + margin, h - margin]),
x = d3.scale.linear().domain([0, data.length]).range([0 + margin, w - margin])

var vis = d3.select("body")
    .append("svg:svg")
    .attr("width", w)
    .attr("height", h)
 
var g = vis.append("svg:g")
    .attr("transform", "translate(0,200)");
    
var line = d3.svg.line()
    .x(function(d,i) { return x(i); })
    .y(function(d) { return -1 * y(d); })

g.append("svg:path").attr("d", line(data));

g.append("svg:line")
    .attr("x1", x(0))
    .attr("y1", -1 * y(0))
    .attr("x2", x(w))
    .attr("y2", -1 * y(0))
 
g.append("svg:line")
    .attr("x1", x(0))
    .attr("y1", -1 * y(0))
    .attr("x2", x(0))
    .attr("y2", -1 * y(d3.max(data)))
    
g.selectAll(".xLabel")
    .data(x.ticks(5))
    .enter().append("svg:text")
    .attr("class", "xLabel")
    .text(String)
    .attr("x", function(d) { return x(d) })
    .attr("y", 0)
    .attr("text-anchor", "middle")
 
g.selectAll(".yLabel")
    .data(y.ticks(4))
    .enter().append("svg:text")
    .attr("class", "yLabel")
    .text(String)
    .attr("x", 0)
    .attr("y", function(d) { return -1 * y(d) })
    .attr("text-anchor", "right")
    .attr("dy", 4)
    
g.selectAll(".xTicks")
    .data(x.ticks(5))
    .enter().append("svg:line")
    .attr("class", "xTicks")
    .attr("x1", function(d) { return x(d); })
    .attr("y1", -1 * y(0))
    .attr("x2", function(d) { return x(d); })
    .attr("y2", -1 * y(-0.3))
 
g.selectAll(".yTicks")
    .data(y.ticks(4))
    .enter().append("svg:line")
    .attr("class", "yTicks")
    .attr("y1", function(d) { return -1 * y(d); })
    .attr("x1", x(-0.3))
    .attr("y2", function(d) { return -1 * y(d); })
    .attr("x2", x(0))</pre>
<p>In this case, I used a style class "<i>values</i>" to recover quickly from the DOM interesting data.</p>
<p>This is the result once generated the graph:</p>
<p><img src="http://blog.redturtle.it/uploads/graph.JPG" alt="graph" class="image-inline" title="graph" /></p>
<p>Of course, this example is simple and fast, but with D3 is possible to create extremely complex graphics, thanks to the flexibility provided by the selectors and the versatility of the data binding (it is interesting, for example, the possibility to recover the data to be processed from external files csv, json, tsv, xml, text ...).</p>
<p>More <a class="external-link" href="https://github.com/mbostock/d3/tree/master/examples">examples</a> are provided in project <a class="external-link" href="https://github.com/mbostock/d3">official page</a> on Github.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrea Baglioni</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Domino</dc:subject>
    
    
      <dc:subject>javascript</dc:subject>
    
    
      <dc:subject>HTML5</dc:subject>
    
    
      <dc:subject>xPages</dc:subject>
    
    <dc:date>2012-10-18T07:30:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/plone-conference-2012-from-redturtles-perspective">
    <title>Plone Conference 2012 from RedTurtle's perspective</title>
    <link>http://blog.redturtle.it/plone-conference-2012-from-redturtles-perspective</link>
    <description>It's all over. 5 days with fellow Plonistas in Arnhem, Netherlands. How was it? Read our summary. One thing we are pretty sure - it was the best conference ever</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>This year's conference was organized for the 10th time by the <a class="external-link" href="http://www.fourdigits.nl/">FourDigits</a> team. They did great job - everything went smoothly - no problems with network, free places in the rooms, video streaming. Even the weather was a pleasant surprise. But above all there were 4 things this conference will be remembered for a very long time:</p>
<p style="text-align:center; "><a href="http://lists.plone.org/pipermail/plone-conference/Week-of-Mon-20121015/000192.html" target="_blank"><img src="http://distilleryimage10.instagram.com/1a8f566e176411e2b09522000a1e9bd5_7.jpg" width="302" /></a><a href="https://twitter.com/optilude/status/256887766221217792" target="_blank"><img src="http://distilleryimage5.s3.amazonaws.com/184e03b214be11e288f622000a1de761_7.jpg" width="302" /></a><br /><a href="https://twitter.com/search?q=%23ploneconf%20party&amp;src=typd"><img src="https://distilleryimage7.s3.amazonaws.com/9a33fcb214c611e2b95b22000a1fab39_7.jpg" width="302" /></a><a href="http://en.wikipedia.org/wiki/Arnhem" target="_blank"><img src="https://o.twimg.com/1/proxy.jpg?t=FQQVBBhMaHR0cDovL2Rpc3RpbGxlcnlpbWFnZTkuaW5zdGFncmFtLmNvbS80OTE2N2NkNDEzMzUxMWUyYjM5ZTIyMDAwYTlkMGRmMV83LmpwZxQCFgASAA&amp;s=Pk5Wsm0M3Ni8aYdDkZRigbjWp-VLIjAesD_gbkV65fE" width="302" /></a></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<h2>Talks worth mentioning</h2>
<p>A very subjective list of talks that you should see. For the full list go to <a href="http://lanyrd.com/2012/ploneconf/schedule/">http://lanyrd.com/2012/ploneconf/schedule/</a></p>
<h3>collective.cover</h3>
<p>Talk presented by Simples Consultoria - Brazilian based Plone company. It's probably the first production deco-like deployment. Interesting use-case. Hopefully it will replace all portletpage-like Plone add'ons.</p>
<p><iframe frameborder="0" height="486" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/14709919?rel=0" width="597"> </iframe></p>
<div><strong> <a href="http://www.slideshare.net/simplesconsultoria/collective-cover" target="_blank" title="Collective Cover">Collective Cover</a> </strong> from <strong><a href="http://www.slideshare.net/simplesconsultoria" target="_blank">Simples Consultoria</a></strong></div>
<p> </p>
<h3>Plone goes social</h3>
<p>Talk presented by Guido Stevens about ligthweight add'on that enables Twitter-like microblogging in Plone. Very clean implementation, no extra dependencies, everything what you need is Plone 4.x and ZODB.</p>
<p><iframe frameborder="0" height="486" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/14700447?rel=0" width="597"> </iframe></p>
<div><strong> <a href="http://www.slideshare.net/GuidoStevens/plone-goes-social" target="_blank" title="Plone goes social">Plone goes social</a> </strong> from <strong><a href="http://www.slideshare.net/GuidoStevens" target="_blank">Guido Stevens</a></strong></div>
<p> </p>
<h3>PloneNG: What's new in Plone 4.2, 4.3 and beyond</h3>
<p>If you are curious to know what you can find in next Plone releases - this presentation by David Glick is a must-seen.</p>
<p><iframe frameborder="0" height="486" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/14698359?rel=0" width="597"> </iframe></p>
<div><strong> <a href="http://www.slideshare.net/davisagli/ploneng-whats-new-in-plone-42-43-and-beyond" target="_blank" title="PloneNG: What's new in Plone 4.2, 4.3, and beyond">PloneNG: What's new in Plone 4.2, 4.3, and beyond</a> </strong> from <strong><a href="http://www.slideshare.net/davisagli" target="_blank">David Glick</a></strong></div>
<p> </p>
<h3>Travis CI: Fun and easy CI for your Plone package</h3>
<p>If you are new to Travis you can learn how to actually use it from those 37 easy slides (by Nejc Zupan).</p>
<p><iframe frameborder="0" height="486" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/14713699" width="597"> </iframe></p>
<div><strong> <a href="http://www.slideshare.net/zupo/travis-ci-fun-and-easy-ci-for-your-plone-packages" target="_blank" title="Travis CI: Fun and easy CI for your Plone packages">Travis CI: Fun and easy CI for your Plone packages</a> </strong> from <strong><a href="http://www.slideshare.net/zupo" target="_blank">Nejc Zupan</a></strong></div>
<p> </p>
<h3>Real-time, collaborative applications in Plone</h3>
<p>A very good summary of what is XMPP, Strophe.js and XMPP-Plone integration in short 20 slides (plus video examples) by Jan-Carel Brand.</p>
<p><iframe frameborder="0" height="486" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/14701136?rel=0" width="597"> </iframe></p>
<div><strong> <a href="http://www.slideshare.net/jcbrand/realtime-collaborative-applications-in-plone" target="_blank" title="Real-time, collaborative applications in Plone">Real-time, collaborative applications in Plone</a> </strong> from <strong><a href="http://www.slideshare.net/jcbrand" target="_blank">jcbrand</a></strong></div>
<p> </p>
<h2>Lighting talks</h2>
<p>Of course every good conference has a bunch of impressive lighting talks. This year it couldn't better. Beneath you can find just a small list of the most impressive ones:</p>
<h3>c2.search.fuzzy - <a href="http://pypi.python.org/pypi/c2.search.fuzzy/">http://pypi.python.org/pypi/c2.search.fuzzy</a></h3>
<p>google-like fuzzy search in Plone. You will never need to repeat your search again :)</p>
<h3>resurrectio - <a href="https://github.com/ebrehault/resurrectio">https://github.com/ebrehault/resurrectio</a></h3>
<p>Resurrectio is a Chrome extension allowing to record a sequence of browser actions and to produce the corresponding CasperJS script.</p>
<h3>buildout bash completition - <a href="https://github.com/specialunderwear/buildout-bash-completion">https://github.com/specialunderwear/buildout-bash-completion</a></h3>
<p>Ever wanted to simply switch between src folder and your buildout root in a flash, check this:</p>
<pre><div id="_mcePaste"> cdco # cd to buildout root</div><div id="_mcePaste"> cds plone.app.package # (will autocomplete with tab and will cd into the project named voxin in the src dir)</div><div id="_mcePaste"> buildout # will run buildout, but from the buildout root.</div><div id="_mcePaste"> ntest # will run ./bin/test (pbp.recipe.noserunner) from the buildout root</div><div id="_mcePaste"> cdomelette # will cd into the omelette dir.</div></pre>
<h3>new Plone events - <a href="https://github.com/plone/plone.app.event">https://github.com/plone/plone.app.event</a></h3>
<p>According to the dev team - it's ready for testing and production - so if you were waiting for the recurrent events - give it a try!</p>
<h3>stxnext.grayscale - <a href="http://pypi.python.org/pypi/stxnext.grayscale">http://pypi.python.org/pypi/stxnext.grayscale</a></h3>
<p>An add-on for Plone that displays the web content of the site in the grayscale colors.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrew Mleczko</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>conference</dc:subject>
    
    
      <dc:subject>eventi</dc:subject>
    
    
      <dc:subject>python</dc:subject>
    
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>community</dc:subject>
    
    
      <dc:subject>sprint</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2012-10-16T12:50:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/plone-registry-strikes-back">
    <title>Plone Registry Strikes Back</title>
    <link>http://blog.redturtle.it/plone-registry-strikes-back</link>
    <description>My journey exploring hidden features of the Plone registry continues. This time we will focus on aspects related to product migration, and how to get a nice user interface for our users
</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>My last post was about <a class="internal-link" href="http://blog.redturtle.it/redturtle/plone.app.registry-how-to-use-it-and-love-it">how to use Plone registry in a clean way</a>, also when storing complex data inside it.</p>
<p>Today we'll talk about the Plone registry again! I've some other tips to share!</p>
<h2>Another good article</h2>
<p>I'm not the only one to be inspired by the registry. After my first article about this subject, I came upon <a class="external-link" href="http://djay.posterous.com/complex-plone-registry-settings-revisted">Complex Plone registry settings revisited</a>. Take a read, is another interesting approach!</p>
<h2>What's new?</h2>
<p>I needed to implement the same product that inspired me for the last article, <a class="external-link" href="http://plone.org/products/collective.analyticspanel/">collective.analyticspanel</a>, with some new features requested by a customer of ours.</p>
<p>Regardless the specific features, what is important is that:</p>
<ul>
<li>it somehow <b>changes the type of one of our existing field;</b></li>
<li>it adds a new field (that should be kept separated from the others).</li>
</ul>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<h3>Changing the field type</h3>
<p><a class="internal-link" href="http://blog.redturtle.it/redturtle/topic_images/collective.analyticspanel-0.2"><img alt="collective.analyticspanel 0.2" class="image-left" src="topic_images/collective.analyticspanel-0.2/@@images/8493ccb2-a735-4a42-9af5-56afba2044a1.png" title="collective.analyticspanel 0.2" /></a>It can be common problem: in <a class="external-link" href="http://pypi.python.org/pypi/collective.analyticspanel/0.2.0">previous version (0.2) of collective.analyticspanel</a> the users were provided with a checkbox (boolean field) named "<i>Apply to the whole subtree</i>".</p>
<p>The customer asked to <b>change the set of possible values</b> from "<i>True or False</i>" to "<i>True, False or False-with-exceptions</i>".</p>
<p>The easiest way of doing it (the Dark Side) is to add a new boolean field (another checkbox). Considering that we were migrating from an old version, this suboptimal solution may indeed be used.</p>
<p>But we should ask ourselves: what kind of control we'd like to see, if we could develop the solution from scratch? For sure, a combobox (so: a Tuple of values).</p>
<p><a class="internal-link" href="http://blog.redturtle.it/pypi-images/collective.analyticspanel/collective.analyticspanel-0.3.0-04.png"><img alt="collective.analyticspanel-0.3.0-04.png" class="image-right" src="../pypi-images/collective.analyticspanel/collective.analyticspanel-0.3.0-04.png/@@images/c8099f6d-0063-45e7-8fbc-abccee193075.png" title="collective.analyticspanel-0.3.0-04.png" /></a>I like the Light Side so, on <a class="external-link" href="http://pypi.python.org/pypi/collective.analyticspanel/0.3.0">version 0.3</a>, I preferred to migrate old Boolean values to the new Tuple.</p>
<p>The way of migrating is to write some Python code during the product upgrade. This is much simpler than you can expect because in fact we are <i>not</i> really changing the field type, as long as we are changing the old name of the field, <code>apply_to_subsection</code> with the more appropriate <code>apply_to</code>.</p>
<p>Thus, we are copying the old (boolean) value to a new (non-boolean) field.</p>
<pre>        ...
        for path_config in old_settings.path_specific_code:
            apply_to_subsection = path_config.apply_to_subsection
            del path_config.apply_to_subsection
            if apply_to_subsection:
                path_config.apply_to = u'subtree'
            else:
                path_config.apply_to = u'context'
        ...
</pre>
<blockquote class="pullquote">Note that our fields are not basic registry elements, but sub-elements of <code>path_config</code>, one of the complex objects we played with in the previous article.</blockquote>
<p>For a complete example see the <a class="external-link" href="https://github.com/RedTurtle/collective.analyticspanel/blob/664486e6f375aa8ea9f6dcc83f5c72bab7624d91/collective/analyticspanel/setuphandlers.py#L45">whole migration code</a>.</p>
<p>So we delete the old (Boolean) value, and translate the new value to a simple string (using the items from the vocabulary of the new combobox).</p>
<h3>I want a new fieldset</h3>
<p>Also the second task implied adding a new field.</p>
<p>Keeping an eye on the usability of the resulting interface, we saw that the form was becoming a little "chaotic" (I like simple forms, don't scare users if you can avoid it!). As the new field's default value is OK for 95% percent of product users, we know that the best choice was to move it into another "<i>Advanced</i>" fieldset.</p>
<p>Now the question is: <b>how to add a fieldset in Plone registry?</b> The only documentation I found is an article from Malthe Borch (the man who saved us all by releasing <a class="external-link" href="http://pypi.python.org/pypi/z3c.jbot">z3c.jbot</a>): "<a class="external-link" href="http://mockit.blogspot.it/2010/12/getting-registry-settings-in-plone-to.html">Getting registry settings in Plone to display in fieldsets</a>".</p>
<p>By following that article, I reached the target. How did it work for my needs?<br />Without registry settings, all fields belong to a "Default" fieldset (not visible in Plone inasmuch as it's the one and only fieldset).</p>
<p>To split fields into more that one fieldset, you need a combination of <a class="external-link" href="https://github.com/RedTurtle/collective.analyticspanel/blob/664486e6f375aa8ea9f6dcc83f5c72bab7624d91/collective/analyticspanel/browser/controlpanel.py#L31">settings via control panel view</a> and <a class="external-link" href="https://github.com/RedTurtle/collective.analyticspanel/blob/664486e6f375aa8ea9f6dcc83f5c72bab7624d91/collective/analyticspanel/interfaces.py#L69">separate interfaces</a>.<br />The general idea is to keep <b>separate interfaces for every fieldset</b>: in that case, the registry needs to use a new interface that <b>inherits from both</b>.</p>
<p>This is how interfaces looks like:</p>
<pre>    class IAnalyticsSettings(Interface):
        """Settings used in the control panel for analyticspanel: general panel
        """
        ... your default fields

    ... 

    class IAnalyticsAdvancedSettings(Interface):
        """Settings used in the control panel for analyticspanel: advanced panel
        """
        ... your advanced field

    ... 

    class IAnalyticsSettingsSchema(IAnalyticsSettings, IAnalyticsAdvancedSettings):
        """Settings used in the control panel for analyticspanel: unified panel
        """
</pre>
<p>And this is how it's handled by control panel:</p>
<pre>    class FormAdvanced(group.Group):
        label = _(u"Advanced settings")
        fields = field.Fields(IAnalyticsAdvancedSettings)

    class AnalyticsSettingsEditForm(controlpanel.RegistryEditForm):
        """Media settings form.
        """
        schema = IAnalyticsSettingsSchema
        fields = field.Fields(IAnalyticsSettings)
        groups = (FormAdvanced,)
        ... 
</pre>
<p>Another important change is in the Generic Setup registration: while the old version of the product was registering the <code>IAnalyticsSettings</code> interface, the new one must register the composed ones: <a class="external-link" href="https://github.com/RedTurtle/collective.analyticspanel/commit/664486e6f375aa8ea9f6dcc83f5c72bab7624d91#L8L0"><code>IAnalyticsSettingsSchema</code></a> (keep this information for later use).</p>
<pre>&lt;registry&gt;<br />    &lt;records interface="collective.analyticspanel.interfaces.IAnalyticsSettingsSchema" /&gt;<br />&lt;/registry&gt;
</pre>
<p><a class="internal-link" href="http://blog.redturtle.it/pypi-images/collective.analyticspanel/collective.analyticspanel-0.3.0-05.png"><img alt="collective.analyticspanel-0.3.0-05.png" class="image-right" src="../pypi-images/collective.analyticspanel/collective.analyticspanel-0.3.0-05.png/@@images/934966b8-d159-4cd1-8550-9393079b508a.png" title="collective.analyticspanel-0.3.0-05.png" /></a>Done! The final result is quite agreeable!</p>
<div class="visualClear"></div>
<h3>Migration</h3>
<p>Let say you are a version 0.2 user, then you migrate to version 0.3 but finally you want to remove the product. In that scenario I found a little issue related to our change of interface.</p>
<p>The old (0.2) uninstall procedure was like this:</p>
<pre>&lt;registry&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettings"<br />            field="general_code"<br />            delete="True"/&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettings"<br />            field="error_specific_code"<br />            delete="True"/&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettings"<br />            field="path_specific_code"<br />            delete="True"/&gt;<br />&lt;/registry&gt;</pre>
<p>The new one (0.3) is this:</p>
<pre>&lt;registry&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettingsSchema"<br />            field="general_code"<br />            delete="True"/&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettingsSchema"<br />            field="error_specific_code"<br />            delete="True"/&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettingsSchema"<br />            field="path_specific_code"<br />            delete="True"/&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettingsSchema"<br />            field="folderish_types"<br />            delete="True"/&gt;<br />&lt;/registry&gt;</pre>
<p>The weird effect of uninstalling 0.3 version of the product is that we still see in the general Plone registry the old values registered through version 0.2.</p>
<p>The solution is simple: during the product migration we shall also run a simple generic setup import step (we named it "<i>clean_registry</i>") that launches an <a class="external-link" href="https://github.com/RedTurtle/collective.analyticspanel/blob/664486e6f375aa8ea9f6dcc83f5c72bab7624d91/collective/analyticspanel/profiles/clean_registry/registry.xml">uninstall procedure that cleans the registry</a> from the values used in old version:</p>
<pre>&lt;registry&gt;<br />    &lt;!-- those registry entries were used in version 0.2 and below --&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettings"<br />            field="general_code"<br />            delete="True"/&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettings"<br />            field="error_specific_code"<br />            delete="True"/&gt;<br />    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettings"<br />            field="path_specific_code"<br />            delete="True"/&gt;<br />&lt;/registry&gt;</pre>
<h2>What about your beloved Plone 3 compatibility?</h2>
<p><a class="internal-link" href="http://blog.redturtle.it/redturtle/topic_images/uglyregistry.png"><img alt="Ugly Plone 3 registry" class="image-right" src="topic_images/uglyregistry.png/@@images/9b769d54-e63f-4924-9818-da070c180d9c.png" title="Ugly Plone 3 registry" /></a>Once again, this product is still compatible with Plone 3 but with limitations:</p>
<ul>
<li>There's a <a class="external-link" href="http://plone.293351.n2.nabble.com/Can-t-load-plone-app-vocabularies-ReallyUserFriendlyTypes-td7558326.html">bug in Plone 3 versions of plone.app.vocabulary</a> so we can't use a combobox with a vocabulary in the Plone registry. So: on Plone 3 we are not using a combobox, but a simple textarea (user can't select values, but need to write them manually)</li>
<li>Fieldsets are not working: luckily you'll get no errors, but simply they are not displayed (and the final UI is really ugly!)</li>
</ul>
<h2>Conclusion</h2>
<p>I hope that this article can help you to maintain order in the Plone registry!</p>
<p><span class="discreet">Photos taken from <a class="external-link" href="http://www.flickr.com/photos/emigepa">emigepa</a></span></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Fabbri</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>tutorials</dc:subject>
    
    
      <dc:subject>Plone Registry</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2012-09-18T08:15:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/plone.app.registry-how-to-use-it-and-love-it">
    <title>plone.app.registry: use it and love it</title>
    <link>http://blog.redturtle.it/plone.app.registry-how-to-use-it-and-love-it</link>
    <description>Once upon a time there was Plone; it used to store its configuration inside a ZMI repository called "Plone Properties Tool"... But time has passed and now Plone is moving to plone.app.registry</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>First of all, let's start reading the <a class="external-link" href="http://pypi.python.org/pypi/plone.app.registry">plone.app.registry</a> description, or better, the <a class="external-link" href="http://pypi.python.org/pypi/plone.registry">plone.registry</a> ones:</p>
<p class="callout"><i>A debconf-like (or about:config-like) registry for storing application settings</i></p>
<p>I think this is great: I really like the <i>about:config</i> page on my Firefox!</p>
<p style="text-align: center; "><img alt="An about:config screenshot" class="image-inline" src="http://blog.redturtle.it/redturtle/topic_images/ffaboutconfig.png/@@images/e2908fbd-c71b-47cf-ba2c-c46f7fd4bf94.png" title="An about:config screenshot" /></p>
<p>This means that there is a unified configuration panel for storing "data", in the most general way. Let me show you some examples:</p>
<ul>
<li>If your application need to store a secret API key...</li>
<li>When your product must store some general installation preference...</li>
<li>If your site need to store <i>something</i> that isn't content specific... </li>
</ul>
<p>...Let's use the registry! Ok, I think you got it. Now, let's see <b>how</b> it works.</p>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText"></div>
<h3>Quick start</h3>
<p>What you'll surely love of plone.app.registry is that you only need to think about <b>data name </b>and<b> data type</b> of what you want to store (as always in Plone, this mean designing the <b>interface</b> through <a class="external-link" href="http://pypi.python.org/pypi/zope.schema">zope.schema</a>).</p>
<pre>class IYourConfiguration(Interface):
    first_data = schema.Text(
            title=_(u"First data needed"),
            required=True,
    )
    second_data = schema.Tuple(
            title=_(u'JavaScript to be included when an error message is get'),
            required=False,
    )
</pre>
<p>Then Plone(.app.registry) will generate for you a proper user interface through <a class="external-link" href="http://pypi.python.org/pypi/z3c.form">z3c.form</a> (another Plone piece that you'll <span style="text-decoration: line-through;"><span>hate</span></span> love).</p>
<p>Anyway, I don't want to digress further. The plone.app.registry documentation is quite clear and there is plenty of examples on web.</p>
<h3>Drawbacks</h3>
<p>I have to admit it, I wasn't a plone.registry enthusiast. I mean, it's a great <i>concept</i>, but when you are using your <i>about:config</i> Mozilla configuration, you don't have to care about all the garbage that a Firefox plugin can leave behind: you can always go there and remove entries manually.</p>
<p>This is not always true with the Plone registry. You have to provide a way to clean things up or configuration will stay there forever. But thing can get even worst: if you are storing complex data types in the registry, you'll need an uninstall procedure that cleans all up, or your registry may be broken.</p>
<p>One thing I've always liked is the easiness of using simple <b>Property Sheet</b> through ZMI (but also nimbly addable using Python or Generic Setup). Those tools are part of Zope and perfectly integrated in ZMI, so a site Manager can always go there and add, update, delete items, so cleaning up is simple.</p>
<p style="text-align: center; "><img alt="ZMI: manage properties sheet" class="image-inline" src="http://blog.redturtle.it/redturtle/topic_images/changeproperties.png/@@images/8246f7c1-e0ea-47c3-b806-b6e64591de7e.png" title="ZMI: manage properties sheet" /></p>
<p>To be brutally honest, using ZMI properties is nearer to the idea of about:config Mozilla-like configuration we know.</p>
<p>However we can't ignore that:</p>
<ul>
<li>Plone is moving on!</li>
<li>plone.app.registry is giving you a Plone-level interface</li>
<li>Site Administrator role can't reach ZMI for manage Zope properties</li>
<li>ZMI properties can't store complex data (only primitive types are handled)</li>
</ul>
<div class="visualClear"><img alt="Complex" class="image-left" src="http://blog.redturtle.it/redturtle/topic_images/complex.png/@@images/e90b0057-3842-4306-8ec3-538075aa85cf.jpeg" title="Complex" />Obviously you can manually create a Plone user interface to handle Zope properties (<i>yes, you can easily do it using again z3c.form</i>), but there's a great feature of plone.app.registry+z3c.form that can really make the difference: <b>building automatically <i>complex</i> configuration interfaces</b>.</div>
<h3 class="visualClear">Going complex</h3>
<p>Recently, in one of our products we needed to store a complex configuration: site administrators had to be able to add a collection of configurations couples. A single set is done by a simple string of information and a long text:</p>
<pre>class IErrorCodeValuePair(Interface):
    message = schema.ASCIILine(title=_(u"Error message"), required=True)
    message_snippet = schema.SourceText(title=_(u"Code to include"), required=False)</pre>
<p>... then you have to write down the configuration registry's interface almost like this:</p>
<pre>class IAnalyticsSettings(Interface):
...
    error_specific_code = schema.Tuple(
        ...
    )
...
</pre>
<p>Now we need to specify what type of element is inside your tuple (in facts: form of form). The great news is that with<b> z3c.form</b> you can easily create a form that handle this kind of complex data!</p>
<pre>class IAnalyticsSettings(Interface):
...
    error_specific_code = schema.Tuple(
        title=_(u'...'),
        ....
        value_type=schema.Object(IErrorCodeValuePair, title=u"..."),
    )</pre>
<p>This will automatically build a form where you can add sub-elements inside, where a single sub-element is composed by the definition of the sub-interface.</p>
<p style="text-align: center; "><img alt="Simple z3c.form rendering example" class="image-inline" src="http://blog.redturtle.it/redturtle/topic_images/simplez3cform.png/@@images/af30bb6a-0404-4f81-a9c5-55ddf214c3d2.png" title="Simple z3c.form rendering example" /></p>
<p>Please note that for now I'm talking about z3c.form only (we are building simply a form, then later on we'll see how to manage what happens when the user press the save button).</p>
<p>Difficulties arise when you need to store those complex values inside the Plone registry. Plone registry explicitly <b>don't want</b> to support the storage of complex data. Motivation of this is one of the drawbacks: if you'll remove the product that own the sub-interface later, your registry will be broken.</p>
<p>Although, keep in mind that saying plone.registry doesn't support this, it doesn't mean that you can't do it. After looking deeply at<b> z3c.form</b> and plone.registry code, and asking on <a class="external-link" href="http://stackoverflow.com/questions/11261682/storing-pairs-of-strings-inside-plone-app-registry">Stackoverflow</a>, I've found a way.</p>
<h3>Store complex data in the Plone registry</h3>
<p>Let's see how to reach this task.</p>
<pre>class IAnalyticsSettings(Interface):
...
    error_specific_code = schema.Tuple(
            title=_(u'...'),
            value_type=PersistentObject(IErrorCodeValuePair, title=_(u"...")),
            required=False,
            default=(),
            missing_value=(),
    )
</pre>
<p>Please note thata the <b><i>PersistentObject</i> <code></code>reference</b> is not part of Plone. As said above, you must explicitly define it:</p>
<pre>from plone.registry.field import PersistentField
...
class PersistentObject(PersistentField, schema.Object):
    pass
</pre>
<p>Another important task is to use the <b>registerFactoryAdapter function</b> of z3c.form.object module:</p>
<pre>from z3c.form.object import registerFactoryAdapter
...
class ErrorCodeValuePair(object):
    implements(IErrorCodeValuePair)
registerFactoryAdapter(IErrorCodeValuePair, ErrorCodeValuePair)
</pre>
<p>That's it. Now you can enjoy your <b>super-complex-form</b> in the Plone registry.</p>
<h3>Clean up, Clean up, Clean up!</h3>
<p>Don't forget what you are doing... you are <b>storing complex alien data</b> in the Plone registry. It's <i>really</i> important to clean things up later, if you (or your users) want to remove your product. This is the difference between love and hate.</p>
<p class="callout"><i>Don't leave garbage behind!</i></p>
<blockquote class="pullquote">This way of cleaning up the registry also works on Plone 3, with plone.app.registry 1.0b1</blockquote>
<p>So: how to clean things up? It's quite simple (but not so clear reading the documentation of plone.app.registry): you simply need to use <b>Generic Setup</b>.</p>
<p>As usual, register your uninstall profile. Then provide to it a <i>registry.xml</i> file with a content like this:</p>
<pre>&lt;registry&gt;
    ...    
    &lt;record interface="collective.analyticspanel.interfaces.IAnalyticsSettings"
	    field="error_specific_code"
            delete="True"/&gt;
    ...
&lt;/registry&gt;
</pre>
<p>This code will remove your data from the Plone registry, then you can safely remove the product.</p>
<h3>Migration</h3>
<p>This is the last problem we need to handle: <b>changes inside the interface definition</b>. What happens if a new release of your product need to add another field to the sub-interface?</p>
<p>Going back to out previous example, it should be something like this:</p>
<pre>class IErrorCodeValuePair(Interface):
    message = schema.ASCIILine(title=_(u"Error message"), required=True)
    message_snippet = schema.SourceText(title=_(u"Code to include"), required=False)<br />    newfield = schema.Bool(title=_(u"..."), required=False, default=True)</pre>
<p>What can the problem be? You stored inside the registry a persistent Object that is not providing the new <i>boolean </i>attribute.</p>
<p>Thankfully, Plone (Plone 3 also) simply shows you an error message when you enter the registry form, so that you are still able to delete old entries manually and add theme from scratch (not very funny for your users).</p>
<p>The best thing you can do is provide a <b>good upgrade</b> to your product, that fix old entries. This is really simple. Follow this example of a proper upgrade step to version 0.2 of your product.</p>
<pre>    registry = queryUtility(IRegistry)
    settings = registry.forInterface(IAnalyticsSettings, check=False)
    for config in settings.error_specific_code:
        if not hasattr(config, 'newfield'):
            config.newfield = True
            logger.info('Added new boolean property "newfield"')
    logger.info('Migrated to version 0.2')</pre>
<h3>As a conclusion, I can say that...</h3>
<p><img alt="Goodbye" class="image-right" src="http://blog.redturtle.it/redturtle/topic_images/goodbye.jpg/@@images/6fcc0df9-4d70-4444-a7c1-8c33823c7c78.jpeg" title="Goodbye" />...now that I have such an easy way to store complex data in my Plone sites without blowing up everything, I see absolutely no reasons not to use plone.app.registry for storing everything I need!</p>
<p>Goodbye property sheet... keep in touch.</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Fabbri</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>Plone Registry</dc:subject>
    
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    <dc:date>2012-07-23T12:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/earthquake-plone-to-the-rescue">
    <title>Earthquake? Plone to the rescue!</title>
    <link>http://blog.redturtle.it/earthquake-plone-to-the-rescue</link>
    <description>To work in Italy you need to be pragmatic. Very pragmatic. That's why when an earthquake hit our region last month we were more than happy to help. Check out what we have done in 72h using Plone, Pyramid and Facebook</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>The idea behind the project is simple: build a tool that will help suffered companies to sell their products. It should be intuitive and integrates with social networks to gain publicity. You probably heard about the <a class="external-link" href="http://www.telegraph.co.uk/news/worldnews/europe/italy/9282504/Italys-cheese-makers-facing-losses-of-200-million-following-earthquake.html">parmigiano reggiano</a> losses and the huge will to buy all the cheese that was left. Our project should help people do it much easier.</p>
<blockquote class="pullquote">Check the site: <a class="external-link" href="http://www.facciamoadesso.it" target="_blank">www.facciamoadesso.it</a></blockquote>
<h3>Plone</h3>
<p>Most of the application is done in Plone, which is so fast to develop nowadays. We have used heavily <a class="external-link" href="http://pypi.python.org/pypi/eea.facetednavigation/4.6">eea.facetednavigation</a> which saved us hours if not days. Big thanks to Alin Voinea, Alexandru Ghica, Antonio De Marinis. You guys rock!</p>
<p>We have implemented a custom facebook integration with a <a class="external-link" href="https://github.com/RedTurtle/restarter.policy/blob/master/src/restarter/policy/plugin.py">separate PAS plugin</a>. We couldn't use plonesocial.auth.rpx cause we wanted to integrate more deeply with facebook app (more about that later), and that will cost a fortune using rpxnow.com.</p>
<p>We have also added a small disqus trick that notifies archetype object owner that somebody made a comment. We are using the callback method:</p>
<pre><br /> function disqus_config() {<br />    this.callbacks.onNewComment = [function(comment) {<br />         $.post('%(document_url)s/disqus_notify', {comment: comment});<br />       }];<br />  }<br /> </pre>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText">and a browser view:</div>
<pre><br /> class Notify(BrowserView):<br />     def __call__(self):<br />         comment_text = self.request.form.get('comment[text]')<br />         comment_id = self.request.form.get('comment[id]')<br />         objectEventNotify(DisqusNotify(self.context, comment_id, comment_text))<br /> </pre>
<p>you can find a working example on <a class="external-link" href="https://github.com/RedTurtle/restarter.policy/blob/master/src/restarter/policy/browser/disqus.py">github</a>.</p>
<p class="mceContentBody documentContent">We have also a separate Zope <a class="external-link" href="https://github.com/RedTurtle/restarter.policy/blob/master/src/restarter/policy/processor.py">process</a> that is <a class="external-link" href="https://github.com/RedTurtle/restarter.policy/blob/master/src/restarter/policy/tool.py">collecting</a> internal stats (products sold, value gained, etc.) mounted in a separate ZODB. In this case we have minimized the problem of ConflictErrors while having the stats always fresh.</p>
<h3>pyramid / celery</h3>
<p>Second important part of the project is the notification app. We are notifying users almost on every single user action (registration, creating company, adding products, buying, commenting, etc.). We are sending 3 types of notifications: email, sms and facebook (using open graph API). We wanted to have something async, easy to implement and stable. Pyramid_celery was the best choice.</p>
<h3>Facebook and Open Graph</h3>
<p>Last important part of the stack is the facebook integration. We wanted something more then simple authentication. We wanted to involved facebook users a bit more. Thanks to <a class="external-link" href="https://developers.facebook.com/docs/opengraph/">Open Graph</a> it's quite easy.</p>
<p>First we have included the basic <i>og</i> meta tags in your <i>&lt;head&gt;</i> section. We have used <a class="external-link" href="http://pypi.python.org/pypi/sc.social.like">an existing Plone product</a> for that. Then we have registered several actions, objects and aggregations that correspondent to notifications I have mentioned before.</p>
<p>One of the action we have is <i>sell</i>. It can be used only with <i>product</i> object. In Plone you need to include in the &lt;head&gt; section of your product object additional meta:</p>
<pre><br /> &lt;meta property="og:type" content="facciamoadesso:product" /&gt;<br /> </pre>
<p>and then using your new action is trivial:</p>
<pre><br /> curl -F 'product=http://example.com/products/my-product' \<br />      'https://graph.facebook.com/me/facciamoadesso:sell'<br /> </pre>
<p>and that's it. Well, almost. You need of course to handle the access_token (we did it with our custom PAS plugin explained above).</p>
<p style="text-align: center; "><iframe align="middle" frameborder="0" height="400" scrolling="no" src="http://www.flickr.com/slideShow/index.gne?set_id=72157630218434554" width="500"></iframe></p>
<h3></h3>
<p>Once again many thanks to all Plone and pyramid developers whose add-ons we have used! It's truly amazing how much you can get in such a short time period.</p>
<p>Last, some code stats:</p>
<ul>
<li><b>21.274 lines of code</b></li>
<li><b>4 contributors</b></li>
<li><b>127 tickets closed</b></li>
<li><b>Most productive between 12:00-13:00 :-)</b></li>
</ul>
<p> </p>
<p class="callout"><b>All the code is open source and can be found on <a class="external-link" href="https://github.com/RedTurtle/restarter.buildout">RedTurtle's</a> github repository</b></p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Andrew Mleczko</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>pyramid</dc:subject>
    
    
      <dc:subject>python</dc:subject>
    
    
      <dc:subject>Plone 4</dc:subject>
    
    
      <dc:subject>plone.it</dc:subject>
    
    
      <dc:subject>community</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    <dc:date>2012-06-27T08:00:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>


  <item rdf:about="http://blog.redturtle.it/slow-plone-site-lets-use-haufe.requestmonitoring">
    <title>Slow Plone site? Let's use haufe.requestmonitoring</title>
    <link>http://blog.redturtle.it/slow-plone-site-lets-use-haufe.requestmonitoring</link>
    <description>Your Plone site suddently become slow, or maybe sometimes it gets slack. How to investigate it (and prevent future problems)</description>
    <content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>One of the worst times for a web programmer or administrator comes when he gets an e-mail like this one: <i>"Hi! The site (you are in charge of) is <b>very</b> slow today! I really cannot work!</i>"</p>
<p><img src="http://blog.redturtle.it/redturtle/topic_images/rabbia.jpg/image_preview" alt="Rabbia" class="image-inline image-inline" title="Rabbia" /></p>
<p>But it can get even worst if you read the mail later, when the problem has already disappeared on his own. So you'll never know if it was a problem of huge (unexpected) traffic or if it's something you'll face again somedays.</p>
<p>If this will arise again soon, you will surely get another e-mail from the same guy, less polite... probably.</p>
<p>Let's examine the problem in depth. This is what you have to do for a Plone site.</p>
<p> </p>
<p> </p>
<p></p>
<a name="anchor-breaktext"></a><div class="breakText"><b>Monitor your Zope installation</b></div>
<p>Always rely on monitor tools! Some example?</p>
<ul>
<li><a class="external-link" href="http://mathias-kettner.de/check_mk.html">Check_MK</a></li>
<li><a class="external-link" href="http://munin-monitoring.org/">Munin</a></li>
</ul>
<p>For Munin, you can also find additional plugin for <a href="http://blog.redturtle.it/redturtle/munin.zope-is-born" class="internal-link">Zope</a> and <a class="external-link" href="http://pypi.python.org/pypi/munin.plone/">Plone</a>.</p>
<p>This kind of tool is very helpful: it warns you when something is going wrong (high memory consumption? disk space down? CPU at 100%?) and collect statistical data, that can be analyzed later.</p>
<p><b>Monitor your running Zope instance</b></p>
<p>If you can reach Plone site ZMI in the very moment it slows down, you can sometimes collect some information from it.</p>
<p>The first (old) product that give us this is <b>DeadlockDebugger </b>(<a class="external-link" href="http://pypi.python.org/pypi/z3c.deadlockdebugger/">z3c.deadlockdebugger</a> is more recent). This product allows you to access a special URL where you can see in real time what Zope threads are doing. If you think this is cool, you have to know that it is<b> </b>commonly suitable only on development environment.</p>
<p>... so what?</p>
<p>If you can access your ZMI root (one level above your Plone site, reach it as a Manager user in the main acl_user, commonly "admin") you can get some general information on thread status from the "<b>Debug Information</b>" section.</p>
<p>You can always reach the top ZMI level using acquisition, even if Zope main folder is not published. Just type <i>http://youssite.com/Control_Panel/manage_main.</i></p>
<p><img src="http://blog.redturtle.it/redturtle/topic_images/Control_Panel_manage_main.png/image_preview" alt="Control Panel" class="image-inline image-inline" title="Control Panel" /></p>
<p>At the bottom level of "Debug Information" view, you can see the connections section.</p>
<p><img src="http://blog.redturtle.it/redturtle/topic_images/Control_Panel_connections.png/image_preview" alt="Threads connections" class="image-inline image-inline" title="Threads connections" /></p>
<p>However, this is not a view for real monitor but when you have no better tool you can find useful information there (sometimes you need to be lucky!).</p>
<p>The tool you really need to have in your Zope installation is <b><a class="external-link" href="http://pypi.python.org/pypi/ZopeHealthWatcher/">ZopeHealthWatcher</a></b>, an evolution of the deadlockdebugging stuff.<br />When configured in your installation you can run a command which dumps the threads status: this way, you will see <i>"what Zope is doing now"</i>.</p>
<p><b>Monitoring long running requests</b></p>
<p>The solutions I just mentioned, however, suffer a big limitation: you must perform analysis  <b>during the slow-down time</b> (commonly, while you are at the  telephone with the <i>this-time-polite-no-more</i> guy that can't work on the  site).</p>
<p>Let's change the subject slightly. You can get some benefit enabling the <b>request response time</b> on your front-end HTTP Web server (for example Apache).</p>
<p>This way you can collect additional HTTP information about how much time is needed to execute <i>each</i> request, then you'll need a tool for parse results (or manually look at them).</p>
<p>Also: this amount of time is not the time that Zope actually needed to perform the request, but the total time of the network behind Apache (net latency, reverse proxy, load balancing software and so on).</p>
<p><b>Monitoring (only) long running requests</b></p>
<p>If the monitor of HTTP response time is good, this is the best solution: <a class="external-link" href="http://pypi.python.org/pypi/haufe.requestmonitoring">haufe.requestmonitoring</a>.</p>
<p class="callout">With Zope and haufe.requestmonitoring<a class="external-link" href="http://pypi.python.org/pypi/haufe.requestmonitoring"></a> you can choose to log in the instance log all requests that require more than a certain amount of time.</p>
<p>So, although the Plone site suddenly goes fast again and you were not able to run your real-time analysis, your Zope instance will contain a set entries like this:</p>
<pre>------
2012-04-22T11:51:52 WARNING RequestMonitor.DumpTrace Long running request
Request 1 "/VirtualHostBase/http/yoursite.com:80/siteid/VirtualHostRoot/foo/foo" running in thread 1096747328 since 10.0001170635s
Python call stack (innermost first)
...</pre>
<p>With thi tool, you have the path request called, the time consumed and a traceback of what Python is doing.</p>
<p>Cool!</p>
<p><b>zope_lrr_analyzer</b></p>
<p><img src="http://blog.redturtle.it/redturtle/topic_images/bottleneck.jpg/image_mini" alt="Bottleneck" class="image-right" title="Bottleneck" />Reading this log is not so simple. All slow-down entries are in the same log of the normal instance activities.</p>
<p>Sometimes if you see that calling an URL takes too much time, it doesn't necessarely mean that <i>that URL</i> is slow: another request probably  freezed Zope.</p>
<p>Also: the same request can be found more than once, so you can read that calling <i>"/mycontent/myview" </i>takes "only" 10 second, while later you have the same record from the same request with a bigger time.</p>
<p>Recently we needed to find the <b>bottleneck</b> on a huge installation (with a lot of running instances). The installation of haufe.requestmonitoring was good, but we needed to obtain a <b>report </b>of slow requests.</p>
<p>To get this we spent a little amount of time<b> writing a parser for Zope instance log</b>, where haufe.requestmonitoring is installed: the <a class="external-link" href="https://github.com/RedTurtle/zope_lrr_analyzer">Zope Long Running Request Analyzer</a>.</p>
<p>It's quick and dirty, but you can use it to find the really-slow request called in your Zope site, and find the bottlenecks.</p>
<p><b>In conclusion...</b></p>
<p>When you have a real bottleneck or problem in your code, logging what Plone is doing can be your silver bullet.</p>
<p>However, do not discard the simple HTTP response time analysis discussed above: remember that not-too-slow request called hundreds of times can make your Plone site slow.</p>
<p>I hope you found here a good tool for you, so that you don't have to meet the <i>never-polite-again</i> guy on the phone!</p>]]></content:encoded>
    <dc:publisher>No publisher</dc:publisher>
    <dc:creator>Luca Fabbri</dc:creator>
    <dc:rights></dc:rights>
    
      <dc:subject>munin</dc:subject>
    
    
      <dc:subject>release</dc:subject>
    
    
      <dc:subject>Plone</dc:subject>
    
    
      <dc:subject>system hang</dc:subject>
    
    <dc:date>2012-05-08T07:15:00Z</dc:date>
    <dc:type>Weblog Entry</dc:type>
  </item>





</rdf:RDF>
