<?xml version="1.0" encoding="utf-8"?>
<!-- generator="Kukkaisvoima version 7" -->
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<channel>
<title>vmx: JavaScript</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi</link>
<description>Blog of Volker Mische</description>
<pubDate>Thu, 01 Aug 2019 22:35:25 +0200</pubDate>
<lastBuildDate>Thu, 01 Aug 2019 22:35:25 +0200</lastBuildDate>
<generator>http://23.fi/kukkaisvoima/</generator>
<language>en</language>
<item>
<title>When npm link fails
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/when-npm-link-fails%3A2019-08-01%3Aen%2CJavaScript%2Cnpm</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/when-npm-link-fails%3A2019-08-01%3Aen%2CJavaScript%2Cnpm#comments</comments>
<pubDate>Thu, 01 Aug 2019 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>JavaScript</category>
<category>npm</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/when-npm-link-fails%3A2019-08-01%3Aen%2CJavaScript%2Cnpm/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>There are cases where linking local packages don't produce the same result as if you would've installed all packages from the registry. Here I'd like to tell the story about one of those real world cases and conclude with a solution to those problems.</p>
<h3>The problem</h3>
<p>When you do an <code>npm install</code> heavy module deduplication and hoisting, which doesn't always behave the same way in all cases. For example if you <code>npm link</code> a package, the resulting node_modules tree is different. This may lead to unexpected runtime errors.</p>
<p>It happened to me recently and I thought I use exactly this real world example to illustrate that problem and a possible solution to it.</p>
<h3>Real world example</h3>
<h4>Preparations</h4>
<p>Start with cloning the <a href="https://github.com/ipfs/js-ipfs-mfs/">js-ipfs-mfs</a> and <a href="https://github.com/ipfs/js-ipfs-unixfs-importer">js-ipfs-unixfs-importer</a> repository:</p>
<pre><code class="language-console">$ git clone https://github.com/ipfs/js-ipfs-mfs --branch v0.12.0 --depth 1
$ git clone https://github.com/ipfs/js-ipfs-unixfs-importer --branch v0.39.11 --depth 1
</code></pre>
<p>Our main module is js-ipfs-mfs and let's say you want to make local changes to js-ipfs-unix-importer, which is a direct dependency of js-ipfs-mfs.</p>
<p>First of all you of course make sure that currently the tests pass (we just run a subset, to get to the actual issue faster). I'm sorry that the installation takes so long and so much space, the dev dependencies are quite heavy.</p>
<pre><code class="language-console">$ cd js-ipfs-mfs
$ npm install
$ npx mocha test/write.spec.js
…
  53 passing (4s)
  1 pending
</code></pre>
<p>Ok, all tests passed.</p>
<h4>Reproducing the issue</h4>
<p>Before we even start modifying js-ipfs-unix-importer, we link it and check that the tests still pass.</p>
<pre><code class="language-console">$ cd js-ipfs-unixfs-importer
$ npm link
$ cd ../js-ipfs-mfs
$ npm link ipfs-unixfs-importer
$ npx mocha test/write.spec.js
…
  37 passing (2s)
  1 pending
  16 failing
…
</code></pre>
<p>Oh, no. The tests failed. But why? The reason is deep down in the code. The root cause is in the [hamt-sharding] module and it's not even a bug. It just <a href="https://github.com/ipfs-shipyard/js-hamt-sharding/blob/1e7e999f5718aad8bdeac37dd41f79e9904b54d4/src/bucket.jsL28-L30">checks if something is a <code>Bucket</code></a>:</p>
<pre><code class="language-JS">static isBucket (o) {
  return o instanceof Bucket
}
</code></pre>
<p><code>instanceof</code> only works if both instances we check on came from the exact same module. Let's see who is importing the hamt-sharding module:</p>
<pre><code class="language-console">$ npm ls hamt-sharding
ipfs-mfs@0.12.0 /home/vmx/misc/protocollabs/blog/when-npm-link-fails/js-ipfs-mfs
├── hamt-sharding@0.0.2
├─┬ ipfs-unixfs-exporter@0.37.7
│ └── hamt-sharding@0.0.2  deduped
└─┬ UNMET DEPENDENCY ipfs-unixfs-importer@0.39.11
  └── hamt-sharding@0.0.2  deduped

npm ERR! missing: ipfs-unixfs-importer@0.39.11, required by ipfs-mfs@0.12.0
</code></pre>
<p>Here we see that ipfs-mfs has a direct dependency on it, and an indirect dependency through ipfs-unixfs-exporter and ipfs-unixfs-importer.
All of them use the same version (0.0.2), hence it's <code>deduped</code> and the <code>instanceof</code> call should work.
But there's also an error about an <code>UNMET DEPENDENCY</code>, the ipfs-unixfs-importer module we linked to.</p>
<p>To make it clear what's happening inside Node.js. When you <code>require('hamt-sharding')</code> from the ipfs-mfs code base, it will load the module from the physical location <code>js-ipfs-mfs/node_modules/hamt-sharding</code>.
When you require it from ipfs-unixfs-importer it will be loaded from <code>js-ipfs-mfs/node_modules/ipfs-unixfs-importer/node_modules/hamt-sharding</code> resp. from <code>ipfs-unixfs-importer/node_modules/hamt-sharding</code>, as <code>js-ipfs-mfs/node_modules/ipfs-unixfs-importer</code> is just a symlink to a symlink to that directory.</p>
<p>When you do a normal installation without linking, you won't have this issue as hamt-sharding will be properly deduplicated and only loaded once from <code>js-ipfs-mfs/node_modules/hamt-sharding</code>.</p>
<h3>Possible workarounds that do not work</h3>
<p>Though you still like to change ipfs-unixfs-importer locally and test those changes with ipfs-mfs without breaking anything. I had several ideas on how to workaround this. I start with the ones that didn't work:</p>
<ol>
<li>Just delete the <code>js-ipfs-unixfs-importer/node_modules/hamt-sharding</code> directory. The module should still be found in the resolve paths of ipfs-mfs. No it doesn't. Tests fail because hamt-sharding can't be found.</li>
<li>Global linking runs an <code>npm install</code> when you run the initial <code>npm link</code>. What if we remove the <code>js-ipfs-unixfs-importer/node_modules</code> completely and symlink to the module manually. That also doesn't work, the hamt-sharding module also can't be found.</li>
<li>Install ipfs-unixfs-importer directly with a relative path (<code>npm install ../js-ipfs-unixfs-importer</code>). No, that doesn't work either, it will still have its own <code>node_modules/hamt-sharding</code>, it won't be properly deduplicated.</li>
</ol>
<p>There must be a way to make local changes to a module and testing them without publishing it each time. Luckily there really is.</p>
<h3>Working workaround</h3>
<p>I'd like to thank my colleague <a href="https://github.com/hugomrdias/">Hugo Dias</a> for this workaround that he has been using for a while already.</p>
<p>You can just replicate what a normal <code>npm install &lt;package&gt;</code> would be doing. You pack the module and then install that packed package. In our case that means:</p>
<pre><code class="language-console">$ cd js-ipfs-mfs
$ npm pack ../js-ipfs-unixfs-importer
…
ipfs-unixfs-importer-0.39.11.tgz
$ npm install ipfs-unixfs-importer-0.39.11.tgz
…
+ ipfs-unixfs-importer@0.39.11
added 59 packages from 76 contributors and updated 1 package in 31.698
</code></pre>
<p>Now all tests pass.</p>
<p>This is quite a manual process. Luckily Hugo created a module to automate exactly that workflow. It's called <a href="https://github.com/hugomrdias/connect-deps/">connect-deps</a>.</p>
<h3>Conclusion</h3>
<p>Sometimes linking packages doesn't create the same structure of modules and you need to use packing instead. To automate this you can use <a href="https://github.com/hugomrdias/connect-deps/">connect-deps</a>.</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/when-npm-link-fails%3A2019-08-01%3Aen%2CJavaScript%2Cnpm/feed/</wfw:commentRss>
</item>
<item>
<title>Joining Protocol Labs
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/joining-protocol-labs%3A2018-01-24%3Aen%2CProtocolLabs%2CIPLD%2CIPFS%2CJavaScript%2CRust%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/joining-protocol-labs%3A2018-01-24%3Aen%2CProtocolLabs%2CIPLD%2CIPFS%2CJavaScript%2CRust%2Cgeo#comments</comments>
<pubDate>Wed, 24 Jan 2018 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>ProtocolLabs</category>
<category>IPLD</category>
<category>IPFS</category>
<category>JavaScript</category>
<category>Rust</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/joining-protocol-labs%3A2018-01-24%3Aen%2CProtocolLabs%2CIPLD%2CIPFS%2CJavaScript%2CRust%2Cgeo/</guid>
<description><![CDATA[ <p>I’m pumped to announce that I’m joining <a href="https://protocol.ai/">Protocol Labs</a> as a software engineer. Those <a href="https://twitter.com/vmx">following me on Twitter</a> or <a href="https://github.com/vmx">looking on my GiHub activity</a> might have already got some hints.</p>
 [...]]]></description>
<content:encoded><![CDATA[
<p>I’m pumped to announce that I’m joining <a href="https://protocol.ai/">Protocol Labs</a> as a software engineer. Those <a href="https://twitter.com/vmx">following me on Twitter</a> or <a href="https://github.com/vmx">looking on my GiHub activity</a> might have already got some hints.</p>
<h3>Short term</h3>
<p>My main focus is currently on <a href="https://ipld.io/">IPLD (InterPlanetary Linked Data)</a>. I’ll smooth things out and also work on the <a href="https://github.com/ipld/specs">IPLD specs</a>, mostly on IPLD Selectors. Those IPLD Selectors will be used to make the underlying graph more efficient to traverse (especially for <a href="https://ipfs.io/">IPFS</a>). That’s a lot of buzzwords, I hope it will get clearer the more I’ll blog about this.</p>
<p>To get started I’ve done the JavaScript IPLD implementations for <a href="https://github.com/ipld/js-ipld-bitcoin">Bitcoin</a> and <a href="https://github.com/ipld/js-ipld-zcash">Zcash</a>. Those are the basis to make easy traversal through the Bitcoin and Zcash blockchains possible.</p>
<h3>Longer term</h3>
<p>In the longer term I’ll be responsible to bring IPLD to <a href="https://www.rust-lang.org/">Rust</a>. That’s especially exciting with Rust’s new <a href="http://webassembly.org/">WebAssembly</a> backend. You’ll get a high performance Rust implementation, but also one that works in Browsers.</p>
<h3>What about Noise?</h3>
<p>Many of you probably know that I’ve been working full-time on <a href="https://noisesearch.org/">Noise</a> for the past 1.5 years. It shapes up nicely and is already quite usable. Of course I don’t want to see this project vanish and it won’t. At the moment I only work part-time at Protocol Labs, to also have some time for Noise. In addition to that there’s also interest within Protocol Labs to use Noise (or parts of it) for better query capabilities. So far it’s only rough ideas I mentioned briefly <a href="https://www.youtube.com/watch?v=wldudAZTM4E&amp;feature=youtu.be&amp;t=11m39s">at the end of my talk about Noise</a> at the [Lisbon IPFS Meetup] two weeks ago. But what’s the distributed web without search?</p>
<h3>What about geo?</h3>
<p>I’m also part of the <a href="https://www.osgeo.org/">OSGeo</a> community and <a href="https://twitter.com/search?q=%2523foss4g">FOSS4G movement</a>. So what’s the future there? I see a lot of potential in the <a href="https://discuss.ipfs.io/t/ipfs-and-sneakernet/1388">Sneakernet</a>. If geo-processing workflows are based around IPFS, you could use the same tools/scripts whether it is stored somewhere in the cloud, or access you local mirror/dump if your Internet connection isn’t that fast/reliable.</p>
<p>I expect non-realiable connectivity to be a hot topic at the <a href="http://2018.foss4g.org/">FOSS4G 2018 conference</a> in Dar es Salaam, Tansania.</p>
<h3>Conclusion</h3>
<p>I’m super excited. It’s a great team and I’m looking forward to push the distributed web a bit forward.</p> ]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/joining-protocol-labs%3A2018-01-24%3Aen%2CProtocolLabs%2CIPLD%2CIPFS%2CJavaScript%2CRust%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>Introduction to Noise’s Node.js API
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/introduction-to-noises-nodejs-api%3A2017-12-21%3Aen%2CNoise%2CNode%2CJavaScript%2CRust</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/introduction-to-noises-nodejs-api%3A2017-12-21%3Aen%2CNoise%2CNode%2CJavaScript%2CRust#comments</comments>
<pubDate>Thu, 21 Dec 2017 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>Noise</category>
<category>Node</category>
<category>JavaScript</category>
<category>Rust</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/introduction-to-noises-nodejs-api%3A2017-12-21%3Aen%2CNoise%2CNode%2CJavaScript%2CRust/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>In the <a href="http://vmx.cx/cgi-bin/blog/index.cgi/exploring-data-with-noise%253A2017-12-12%253Aen%252CNoise%252CNode%252CJavaScript%252CRust">previous blog post about Noise</a> we imported data with the help of some already prepared scripts. This time it’s an introduction in how to use <a href="https://noisesearch.org/">Noise</a>‘s <a href="https://github.com/pipedown/node-noise/">Promise-based Node.js API</a> directly yourself.</p>
<p>The dataset we use is not a ready to use single file, but one that consists of several ones. The data is the “Realized Cost Savings and Avoidance” for US government agencies. I’m really excited that such data gets openly published as JSON. I wished Germany would be that advanced in this regard. If you want to know more about the structure of the data, there’s documentation about the [JSON Schmema], they even have a “<a href="https://management.cio.gov/schemaexamples/JSON%20User%20Guide_v5.pdf">OFCIO JSON User Guide for Realized Cost Savings</a>” on how to produce the data out of Excel.</p>
<p>I’ve prepared a <a href="https://github.com/vmx/blog-introduction-to-noises-nodejs-api">repository containing the final code and the data</a>. But feel free to follow along this tutorial by yourself and just point to the <code>data</code> directory of that repository when running the script.</p>
<p>Let’s start with the boilerplate code for reading in those files and parsing them as JSON. But first create a new package:</p>
<pre><code>mkdir noise-cost-savings
cd noise-cost-savings
npm init --force
</code></pre>
<p>You can use <code>--force</code> here as you probably won’t publish this package anyway. Put the boilerplate code below into a file called <code>index.js</code>. Please note that the code is kept as simple as possible, for a real world application you surely want better error handling.</p>
<pre><code>#!/usr/bin/env node
'use strict';

const fs = require('fs');
const path = require('path');

// The only command line argument is the directory where the data files are
const inputDir = process.argv[2];
console.log(`Loading data from ${inputDir}`);

fs.readdir(inputDir, (_err, files) =&gt; {
  files.forEach(file =&gt; {
    fs.readFile(path.join(inputDir, file), (_err, data) =&gt; {
      console.log(file);
      const json = JSON.parse(data);
      processFile(json);
    });
  });
});

const processFile = (data) =&gt; {
  // This is where our actual code goes
};
</code></pre>
<p>This code should already run. Checkout my repository with the data into some directory first:</p>
<pre><code>git clone https://github.com/vmx/blog-introduction-to-noises-nodejs-api
</code></pre>
<p>Now run the script from above as:</p>
<pre><code>node index.js &lt;path-to-directory-from-my–repo-mentioned-above&gt;/data
</code></pre>
<p>Before we take a closer look at the data, let’s install the Noise module. Please note that you need to have <a href="https://www.rust-lang.org/">Rust</a> installed (easiest is probably through <a href="https://www.rustup.rs/">rustup</a>) before you can install Noise.</p>
<pre><code>npm install noise-search
</code></pre>
<p>This will take a while. So let’s get back to code. Load the <code>noise-search</code> module by adding:</p>
<pre><code>const noise = require('noise-search');
</code></pre>
<p>A Noise index needs to be opened and closed properly, else your script will hang and not terminate. Opening a new Noise index is easy. Just put this before reading the files:</p>
<pre><code>const index = noise.open('costsavings', true);
</code></pre>
<p>It means that open an index called <code>costsavings</code> and create it if it doesn’t exist yet (that’s the boolean <code>true</code>). Closing the index is more difficult due to the asynchronous nature of the code. We can close the index only after all the processing is done. Hence we wrap the <code>fs.readFile(…)</code> call in a Promise. So that new code looks like this:</p>
<pre><code>fs.readdir(inputDir, (_err, files) =&gt; {
  const promises = files.map(file =&gt; {
    return new Promise((resolve, reject) =&gt; {
      fs.readFile(path.join(inputDir, file), (err, data) =&gt; {
        if (err) {
          reject(err);
          throw err;
        }

        console.log(file);
        const json = JSON.parse(data);
        resolve(processFile(json));
      });
    });
  });
  Promise.all(promises).then(() =&gt; {
    console.log(&quot;Done.&quot;);
    index.close();
  });
});
</code></pre>
<p>If you run the script now it should print out the file names as before and terminate with a <code>Done.</code>. There got a directory called <code>costsavings</code> created after you ran the script. This is where the Noise index is stored in.</p>
<p>Now let’s have a look at the data files, e.g. the <a href="https://github.com/vmx/blog-introduction-to-noises-nodejs-api/blob/master/data/commerce.json">cost savings file from the Department of Commerce</a> (or the <a href="https://management.cio.gov/schema/#savings">JSON Schema</a>), you’ll see that it has a single field called <code>&quot;strategies&quot;</code>, which contains an array with all strategies. We are free to pre-process the data as much as we want before we insert it into Noise. So let’s create a separate document for every strategy. Our <code>processFile()</code> function now looks like:</p>
<pre><code>const processFile = (data) =&gt; {
  data.strategies.forEach(async strategy =&gt; {
    // Use auto-generated Ids for the documents
    await index.add(strategy);
  });
};
</code></pre>
<p>Now all the strategies get inserted. Make sure you delete the index (the <code>costsavings</code> directory) if you re-run the scripts, else you would end up with duplicated entries, as different Ids will be generated on every run.</p>
<p>To query the index you could use the <a href="https://github.com/vmx/noise-indexserve">Noise indexserve script</a> that I’ve also used in the <a href="http://vmx.cx/cgi-bin/blog/index.cgi/exploring-data-with-noise%253A2017-12-12%253Aen%252CNoise%252CNode%252CJavaScript%252CRust">last blog post about Noise</a>. Or we just add a small query at the end of the script after the loading is done. Our query function will do the query and output the result:</p>
<pre><code>const queryNoise = async (query) =&gt; {
  const results = await index.query(query);
  for (const result of results) {
    console.log(result);
  }
};
</code></pre>
<p>There’s not much to say, except it’s again a Promised-based API. And now hook up this function after the loading and before the index is closed. For that, replace the <code>Promise.all(…)</code> call with:</p>
<pre><code>Promise.all(promises).then(async () =&gt; {
  await queryNoise('find {} return count()');
  console.log(&quot;Done.&quot;);
  index.close();
});
</code></pre>
<p>It’s a really simple query, it just returns the number of documents that are in there (644). After all this hard work, it’s time to make a more complicated query on this dataset to show that it was worth doing all this. Let’s return the total net savings of all agencies in 2017. Replace the query <code>find {} return count()</code> with:</p>
<pre><code>find {fy2017: {netOrGross: == &quot;Net&quot;}} return sum(.fy2017.amount)
</code></pre>
<p>That’s $845m savings. Not bad at all!</p>
<p>You can learn more about the Noise Node.js API from the <a href="https://github.com/pipedown/node-noise/#readme">README at the corresponding repository</a>. If you want to learn more about possible queries, have a look at the <a href="https://github.com/pipedown/noise/blob/master/query_language_reference.md">Noise Query Language reference</a>.</p>
<p>Happy cost saving!</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/introduction-to-noises-nodejs-api%3A2017-12-21%3Aen%2CNoise%2CNode%2CJavaScript%2CRust/feed/</wfw:commentRss>
</item>
<item>
<title>Exploring data with Noise
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/exploring-data-with-noise%3A2017-12-12%3Aen%2CNoise%2CNode%2CJavaScript%2CRust</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/exploring-data-with-noise%3A2017-12-12%3Aen%2CNoise%2CNode%2CJavaScript%2CRust#comments</comments>
<pubDate>Tue, 12 Dec 2017 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>Noise</category>
<category>Node</category>
<category>JavaScript</category>
<category>Rust</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/exploring-data-with-noise%3A2017-12-12%3Aen%2CNoise%2CNode%2CJavaScript%2CRust/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>This is a quick introduction on how to explore some JSON data with <a href="https://noisesearch.org/">Noise</a>. We won’t do any pre-processing, but just load the data into Noise and see what we can do with it. Sometimes the JSON you get needs some tweaking before further analysis makes sense. For example you want to rename fields or numbers are stored as string. This exploration phase can be used to get a feeling for the data and which parts might need some adjustments.</p>
<p>Finding decent ready to use data that contains some nicely structured JSON was harder than I thought. Most datasets are either GeoJSON or CSV masqueraded as JSON. But I was lucky and found a <a href="https://www.circl.lu/opendata/">JSON dump of the CVE database provided by CIRCL</a>. So we’ll dig into the CVEs (<a href="https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures">Common Vulnerabilities and Exposures</a>) database to find out more about all those security vulnerabilities.</p>
<p>Noise has a <a href="https://github.com/pipedown/node-noise">Node.js binding</a> to get started easily. I won’t dig into the API for now. Instead I’ve prepared two scripts. One to load the data from a file containing new line separated JSON. And another one for serving up the Noise index over HTTP, so that we can explore the data via <a href="https://curl.haxx.se/">curl</a>.</p>
<h3>Prerequisites</h3>
<p>As we use the Node.js binding for Noise, you need to have Node.js, npm and Rust (easiest is probably through <a href="https://www.rustup.rs/">rustup</a>) installed.</p>
<p>I’ve created a repository with the two scripts mentioned above plus a subset of the CIRCL CVE dataset. Feel free to download the full dataset from the <a href="https://www.circl.lu/opendata/">CIRCL Open Data page</a> (1.2G unpacked) and load it into Noise. Please note that Noise isn’t performance optimised at all yet. So the import takes some time as the hard work of all the indexing is done on insertion time.</p>
<pre><code>git clone https://github.com/vmx/blog-exploring-data-with-noise
cd blog-exploring-data-with-noise
npm install
</code></pre>
<p>Now everything we need should be installed, let’s load the data into Noise and do a query to verify it’s installed properly.</p>
<h3>Loading the data and verify installation</h3>
<p>Loading the data is as easy as:</p>
<pre><code>npx dataload circl-cve.json
</code></pre>
<p>For every inserted record one dot will be printed.</p>
<p>To spin up the simple HTTP server, just run:</p>
<pre><code>npx indexserve circl-cve
</code></pre>
<p>To verify it does actually respond to queries, try:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {} return count()'
</code></pre>
<p>If all documents got inserted correctly it should return</p>
<pre><code>[
1000
]
</code></pre>
<p>Everything is set up properly, now it’s time to actually exploring the data.</p>
<h3>Exploring the data</h3>
<p>We don’t have a clue yet, what the data looks like. So let’s start with looking at a single document:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {} return . limit 1'
[
{
  &quot;Modified&quot;: &quot;2017-01-02 17:59:00.147000&quot;,
  &quot;Published&quot;: &quot;2017-01-02 17:59:00.133000&quot;,
  &quot;_id&quot;: &quot;34de83b0d3c547c089635c3a8b4960f2&quot;,
  &quot;cvss&quot;: null,
  &quot;cwe&quot;: &quot;Unknown&quot;,
  &quot;id&quot;: &quot;CVE-2017-5005&quot;,
  &quot;last-modified&quot;: {
    &quot;$date&quot;: 1483379940147
  },
  &quot;references&quot;: [
    &quot;https://github.com/payatu/QuickHeal&quot;,
    &quot;https://www.youtube.com/watch?v=h9LOsv4XE00&quot;
  ],
  &quot;summary&quot;: &quot;Stack-based buffer overflow in Quick Heal Internet Security 10.1.0.316 and earlier, Total Security 10.1.0.316 and earlier, and AntiVirus Pro 10.1.0.316 and earlier on OS X allows remote attackers to execute arbitrary code via a crafted LC_UNIXTHREAD.cmdsize field in a Mach-O file that is mishandled during a Security Scan (aka Custom Scan) operation.&quot;,
  &quot;vulnerable_configuration&quot;: [],
  &quot;vulnerable_configuration_cpe_2_2&quot;: []
}
]
</code></pre>
<p>The query above means: “Find all documents without restrictions and return it’s full contents. Limit it to a single result”.</p>
<p>You don’t always want to return all documents, but filter based on certain conditions. Let’s start with the word match operator <code>~=</code>. It matches document which contains those words in a specific field, in our case <code>&quot;summary&quot;</code>. As “buffer overflow” is a common attack vector, let’s search for all documents that contain it in the summary.</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {summary: ~= &quot;buffer overflow&quot;}'
[
&quot;34de83b0d3c547c089635c3a8b4960f2&quot;,
&quot;8dff5ea0e5594e498112abf1c222d653&quot;,
&quot;741cfaa4b7ae43909d1da153747975c9&quot;,
…
&quot;b7419042c9464a7b96d3df74451cb4a7&quot;,
&quot;d379e9fda704446982cee8638f32e72b&quot;
]
</code></pre>
<p>That’s quite a long list of random characters. Noise assigns Ids to every inserted document if the document doesn’t contain a <code>&quot;_id&quot;</code> field. By default Noise returns such Ids of the matching documents. So no return value is equivalent to <code>return ._id</code>. Let’s return the CVE number of the matching vulnerabilities instead. That field is called <code>&quot;id&quot;</code>:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {summary: ~= &quot;buffer overflow&quot;} return .id'
[
&quot;CVE-2017-5005&quot;,
&quot;CVE-2016-9942&quot;,
…
&quot;CVE-2015-2710&quot;,
&quot;CVE-2015-2666&quot;
]
</code></pre>
<p>If you want to know how many there are, just append a <code>return count()</code> to the query:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {summary: ~= &quot;buffer overflow&quot;} return count()'
[
61
]
</code></pre>
<p>Or we can of course return the full documents to see if there are further interesting things to look at:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {summary: ~= &quot;buffer overflow&quot;} return .'
…
</code></pre>
<p>I won’t post the output here, it’s way too much. If you scroll through the output, you’ll see that some contain a field named <code>&quot;capec&quot;</code>, which is probably about the <a href="https://capec.mitre.org/about/index.html">Common Attack Pattern Enumeration and Classification</a>. Let’s have a closer look at one of those, e.g. from “CVE-2015-8388”:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {id: == &quot;CVE-2015-8388&quot;} return .capec'
[
[
  {
    &quot;id&quot;: &quot;15&quot;,
    &quot;name&quot;: &quot;Command Delimiters&quot;,
    &quot;prerequisites&quot;: …
    &quot;related_weakness&quot;: [
      &quot;146&quot;,
      &quot;77&quot;,
      …
    ],
    &quot;solutions&quot;: …
    &quot;summary&quot;: …
  },
  …
</code></pre>
<p>This time we’ve used the exact match operator <code>==</code>. As the CVEs have a unique Id, it only returned a single document. It’s again a lot of data, we might only care about the CAPEC names, so let’s return those:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {id: == &quot;CVE-2015-8388&quot;} return .capec[].name'
[
[
  &quot;Command Delimiters&quot;,
  &quot;Flash Parameter Injection&quot;,
  &quot;Argument Injection&quot;,
  &quot;Using Slashes in Alternate Encoding&quot;
]
]
</code></pre>
<p>Note that it is an array of an array. The reason is that in this case we only return the CAPEC names of a single document, but our filter condition could of course match more documents, like the word match operator did when we were searching for “buffer overlow”.</p>
<p>Let’s find out all CVEs where the CAPEC name “Directory Traversal”.</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {capec: [{name: == &quot;Command Delimiters&quot;}]} return .id'
[
&quot;CVE-2015-8389&quot;,
&quot;CVE-2015-8388&quot;,
&quot;CVE-2015-4244&quot;,
&quot;CVE-2015-4224&quot;,
&quot;CVE-2015-2265&quot;,
&quot;CVE-2015-1986&quot;,
&quot;CVE-2015-1949&quot;,
&quot;CVE-2015-1938&quot;
]
</code></pre>
<p>The CAPEC data also contains references to related weaknesses as we’ve seen before. Let’s return the <code>related_weakness</code> of all CVEs that have the CAPEC name “Command Delimiters”.</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {capec: [{name: == &quot;Command Delimiters&quot;}]} return {cve: .id, related: .capec[].related_weakness}'
[
{
  &quot;cve&quot;: &quot;CVE-2015-8389&quot;,
  &quot;related&quot;: [
    [
      &quot;146&quot;,
      &quot;77&quot;,
      …
    ],
    [
      &quot;184&quot;,
      &quot;185&quot;,
      &quot;697&quot;
    ],
    …
  ]
},
{
  &quot;cve&quot;: &quot;CVE-2015-8388&quot;,
  &quot;related&quot;: [
  …
  ]
},
…
]
</code></pre>
<p>That’s not really what we were after. This returns the related weaknesses of <em>all</em> CAPECs and not just the one named “Command Delimiters”. The solution is a so called bind variable. You can store an array element that matches a condition in a variable which can then be re-used in the return value.</p>
<p>Jut prefix the array condition with a variable name separated by two colons:</p>
<pre><code>find {capec: commdelim::[{name: == &quot;Command Delimiters&quot;}]}
</code></pre>
<p>And use it in the return value like any other path:</p>
<pre><code>return {cve: .id, related: commdelim.related_weakness}
</code></pre>
<p>So the full query is:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {capec: commdelim::[{name: == &quot;Command Delimiters&quot;}]} return {cve: .id, related: commdelim.related_weakness}'
[
{
  &quot;cve&quot;: &quot;CVE-2015-8389&quot;,
  &quot;related&quot;: [
    [
      &quot;146&quot;,
      &quot;77&quot;,
      …
    ]
  ]
},
{
  &quot;cve&quot;: &quot;CVE-2015-8388&quot;,
  &quot;related&quot;: [
    [
      &quot;146&quot;,
      &quot;77&quot;,
      …
    ]
  ]
},
…
]
</code></pre>
<p>The result isn’t that exciting as it’s the same related weaknesses for all CVEs, but of course the could be completely arbitrary. There’s no limitation on the schema.</p>
<p>So far we haven’t done any range requests yet. So let’s have a look at all CVEs that were last modified on December 28th with “High” severity rating according to the <a href="https://nvd.nist.gov/vuln-metrics/cvss">Common Vulnerability Scoring System</a>. First we need to determine the correct timestamps:</p>
<pre><code>date --utc --date=&quot;2016-12-28&quot; &quot;+%s&quot;
1482883200
date --utc --date=&quot;2016-12-29&quot; &quot;+%s&quot;
1482969600
</code></pre>
<p>Please note that the <code>&quot;last-modified&quot;</code> field has timestamps with 13 characters (ours have 10), which means that they are in milliseconds, so we just append three zeros and we’re good. The severity rating is stored in the field <code>&quot;cvss”</code>, “High” severity means a value from 7.0–8.9. We need to put the field name <code>last-modified</code> in quotes as it contains a dash (just as you’d do it in JavaScript). The final query is:</p>
<pre><code>curl -X POST http://127.0.0.1:3000/query -d 'find {&quot;last-modified&quot;: {$date: &gt;= 1482883200000, $date: &lt; 1482969600000}, cvss: &gt;= 7.0, cvss: &lt;=8.9} return .id'
[
&quot;CVE-2015-4199&quot;,
&quot;CVE-2015-4200&quot;,
&quot;CVE-2015-4224&quot;,
&quot;CVE-2015-4227&quot;,
&quot;CVE-2015-4230&quot;,
&quot;CVE-2015-4234&quot;,
&quot;CVE-2015-4208&quot;,
&quot;CVE-2015-4526&quot;
]
</code></pre>
<p>This was an introduction into basic querying of Noise. If you want to know about further capabilities you can have a look at the <a href="https://github.com/pipedown/noise/blob/master/query_language_reference.md">Noise Query Language reference</a> or stay tuned for further blog posts.</p>
<p>Happy exploration!</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/exploring-data-with-noise%3A2017-12-12%3Aen%2CNoise%2CNode%2CJavaScript%2CRust/feed/</wfw:commentRss>
</item>
<item>
<title>LXJS 2013
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2013%3A2013-10-06%3Aen%2CJavaScript%2Cconference</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2013%3A2013-10-06%3Aen%2CJavaScript%2Cconference#comments</comments>
<pubDate>Sun, 06 Oct 2013 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>JavaScript</category>
<category>conference</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2013%3A2013-10-06%3Aen%2CJavaScript%2Cconference/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>The <a href="http://lxjs.org/">LXJS conference</a> was a blast like last year. Well organized, great speakers, nice parties and an overwhelming overall atmosphere. It's definitely a conference that is in my regular schedule.</a>

<h2>The talks</h2>

<p>It was a pleasure to see such a variety of different talk styles. Whenever you get invited/accepted to give a talk at the LXJS, be sure your presentation style is outstanding. My two favourite ones were <a href="http://youtu.be/ekvaKmVfjtc">Michal Budzynski – Firefox OS army!</a> and <a href="http://youtu.be/zsbNVkayYRQ">Jonathan Lipps – mobile automation made awesome</a>. Playing games on stage or singing songs is something you won't see at many other conferences.
</p>

<p>Another presentation I really enjoyed was one about <a href="http://youtu.be/UOM5eY5hG-Q">designing for accessibility</a>. <a href="http://laurakalbag.com/">Laura Kalbag</a> did really get the message across and showed great examples.
</p>

<p>Interesting was also the talk <a href="http://youtu.be/G1QCBzQ0aNc">Digital Feudalism & How to Avoid It</a>. It was about user experience and touched a lot of topics, from business models over privacy to the problems of open source. I really like the whole presentation, from the contents to the presentation style. But sadly only up to shortly before the end of the talk. <a href="http://aralbalkan.com/">Aral Balkan</a> closed with his new startup that creates a new phone with overall great experience. As far as I know there's no information available on what <a href="http://codename-prometheus.eu/">Codename Prometheus</a> will be based on. If it's based on <a href="http://firefoxos.com/">Firefox OS</a> I can see the point, if it's something custom I see doomed to fail.
</p>

<p>A really enjoyable talk came from <a href="http://mrale.ph/">Vyacheslav Egorov</a>. It was about <a href="http://youtu.be/65-RbBwZQdU">microbenchmarking pitfalls</a> and had great depth, while being super entertaining.
</p>

<h2>The people</h2>

<p>I've met a lot new ones and plenty of people I already know. It was a good mixture with many great conversations. There's not really a point mentioning all of them, you know who you are.
</p>

<p>On the boat trip I learned that <a href="http://www.ci.mtnview.ca.us/">Mountain View</a> (<em>that link is funnier than I've thought, given that's a blog about a JavaScript conference</em>) not one of the most boring places but actually has something to over if you life there (recommend for young singles).</p>


<h2>The conference itself</h2>

<p>The conference was very well organized. Thanks <a href="https://twitter.com/daviddias">David Dias</a> and all the others that organized that event  (<em>here should be a link, but I couldn't found one to the organizers</em>). Having a cinema as a venue is always nice. Comfortable seats and a big canvas for presentation.
</p>

<p>Live streaming of the talks and <a href="http://www.youtube.com/channel/UCiCGpqnkj9oRzPsJBql7pGw">having them available immediately afterwards on YouTube</a> is really really nice. So even if you can't attend you still get all the great talks if you want to.
</p>

<p>The only critique I have is the lunch. Those baguettes were OK and I didn't leave hungry, but the food last time was just so much better.
</p>

<h2>Conclusion</h2>

<p>The <a href="http://2013.lxjs.org/">LXJS 2013</a> was a great and I'm looking forward to see everyone again at this well organized conference next year!
</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2013%3A2013-10-06%3Aen%2CJavaScript%2Cconference/feed/</wfw:commentRss>
</item>
<item>
<title>LXJS 2012
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2012%3A2012-10-01%3Aen%2CJavaScript%2Cconference</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2012%3A2012-10-01%3Aen%2CJavaScript%2Cconference#comments</comments>
<pubDate>Mon, 01 Oct 2012 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>JavaScript</category>
<category>conference</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2012%3A2012-10-01%3Aen%2CJavaScript%2Cconference/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>The LXJS conference was really a blast. Well organized, great speakers, nice parties and an overwhelming overall atmosphere. My talk about bidirectional transformations also went well.</p>

<h2>My talk</h2>

<p>With my talk "Bidirectional transformations with lenses", it's been the first time I've talked about something not directly geo-related at a conference, though I couldn't leave out some references to the geo world. The whole topic would deserves a blog post on its own, hence I'll just leave a reference to the <a href="http://vmx.cx/blog/2012-10-01/">slides of my talk, <a href="http://www.youtube.com/watch?v=qKnZk27E9Uc&list=PLt4dwg5cC5TR2cW_QQfR3Po7teWbi81Ms">the recording from LXJS</a> and the <a href="https://github.com/vmx/jslens">Github repository of jslens</a>.</p>

<h2>The others talks</h2>

<p>Most talks were of high quality and it was a great to learn about new things. Highlights for me were the talks about Fireworks (where there doesn't seem to be a recording of), the one about <a href="http://www.youtube.com/watch?v=jl5v3bsMH_E&list=PLt4dwg5cC5TR2cW_QQfR3Po7teWbi81Ms">Helicopters</a>, the one about <a href="http://www.youtube.com/watch?v=9PK68ZKcSEk&list=PLt4dwg5cC5TSqHR44YK0UQ_8TSG8YtZtI">how to manage open source projects properly</a> and <a href="http://www.youtube.com/watch?v=FYed4dYVtJA&list=PLt4dwg5cC5TR2cW_QQfR3Po7teWbi81Ms">Jan's talk about Javascript's world domination</a> that made me think.</p>

<p>All presentations were recorded, so you can <a href="http://www.youtube.com/user/lxjs2012/videos?flow=grid&view=1">watch them now</a> to find out what you've missed out.

<h2>Format of the conference</h2>

<p>It was the first single-track conference I've been to and I really liked it. Everyone got to see the same presentations and you don't feel like you've missed something. As a speaker you have the advantage of not having some well known person at the same time which draws away the attendees from your talk. Everything is focused around a single stage where everyone is excited about what is next.</p>

<p>The talks where always grouped into certain categories, that made a lot of sense. Though it was a bit strange to hear about new JavaScript based languages in two different slots.</p>

<h2>The events around the conference</h2>

<p>The conference had a pre, middle and after party. It was really good to get in touch with people there. I also liked the idea to not making a difference between the speakers and the attendees with a speakers dinner or something similar. For the after-after party a huge group of people just kept on having fun. The people didn't split as much as I would've expected it. This speaks for the great atmosphere and the nice group of attendees.</p>

<h2>Conclusion</h2>

<p>I really had a great time and it was fun to meet so many old friends from the CouchOne days, but also to meet a lot of interesting new people. I'm really looking forward to the 2013 edition of the LXJS.</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/lxjs-2012%3A2012-10-01%3Aen%2CJavaScript%2Cconference/feed/</wfw:commentRss>
</item>
<item>
<title>FOSS4G 2011: Report
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2011%3A2011-09-20%3Aen%2CCouchDB%2CGeoCouch%2CMapQuery%2CErlang%2CJavaScript%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2011%3A2011-09-20%3Aen%2CCouchDB%2CGeoCouch%2CMapQuery%2CErlang%2CJavaScript%2Cgeo#comments</comments>
<pubDate>Tue, 20 Sep 2011 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>GeoCouch</category>
<category>MapQuery</category>
<category>Erlang</category>
<category>JavaScript</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2011%3A2011-09-20%3Aen%2CCouchDB%2CGeoCouch%2CMapQuery%2CErlang%2CJavaScript%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>The <a href="http://2011.foss4g.org/">FOSS4G 2011</a> is over now. Time for a small report. The crowd was amazing and it was again the ultimate gathering of the Free and Open Source for Geospatial developer tribe. Solid presentations and great evenings.</p>

<h3>My talk: The State of GeoCouch</h3>

<p>I'm really happy how <a href="http://2011.foss4g.org/sessions/state-geocouch">my talk</a> went, I really enjoyed it. The were lots of people (although there was a talk from Frank Warmerdam at the same time) asking interesting questions at the end.
</p>

<p>The talk is not only about <a href="https://github.com/couchbase/geocouch">GeoCouch</a> but also gives you an overview of some of the features it leverages from <a href="http://couchdb.apache.org/">Apache CouchDB</a>. In the end you should have an overview why you might want to use GeoCouch for your next project.
</p>
<p>You can get the slides right here.</p>
<ul>
  <li>The slides (download optimized)
<a href="/blog/2011-09-20/the-state-of-geocouch.pdf">as PDF</a> (licensed under
<a href="http://creativecommons.org/licenses/by/3.0/de/">CC-BY-3.0-de</a>).</li>
  <li>The slides with comments
<a href="/blog/2011-09-20/the-state-of-geocouch.html">as HTML</a> (licensed under
<a href="http://creativecommons.org/licenses/by/3.0/de/">CC-BY-3.0-de</a>).</li>
  <li><a href="http://www.fosslc.org/drupal/content/state-geocouch">The slides with audio</a>. It’s the recording of the actual talk at the conference.</li>
</ul>

<h3>Other talks</h3>

<p>I was happy to see that there was <a href="http://2011.foss4g.org/sessions/new-geodata-tool-set-couchdb-and-nodejs">another talk about GeoCouch</a>. Other talks I really enjoyed were:</p>
<ul>
  <li><a href="http://2011.foss4g.org/sessions/cartoset-new-foss-create-highly-visual-geo-portals">CartoSet, a new FOSS to create highly visual geo portals</a>: So many true things were said, e.g. get the data from the customer first, before you start building anything.
  </li>
  <li><a href="http://2011.foss4g.org/sessions/introduction-opensource-webmapping-beyond-google-maps">Introduction to OpenSource WebMapping: Beyond Google Maps</a>: A very nice introduction off the full stack for web mapping. From the database, over the server to the client. It's for people that have no clue that they could have maps on their own infrastructure.
  </li>
  <li><a href="http://2011.foss4g.org/sessions/comparing-geoext-mapquery-and-legato-technical-and-collaborative-point-view">Comparing GeoExt, MapQuery and Legato from a technical and collaborative point of view</a>: A good comparison between <a href="http://geoext.org/">GeoExt</a>, <a href="http://mapquery.org/">MapQuery</a> and <a href="http://www.legato.net">Legato</a>. I especially liked the “Bodo”-test.
  </li>
  <li><a href="http://2011.foss4g.org/sessions/beyond-vectors-adapting-remote-sensing-research-environmental-monitoring-open-source-hardwa">Beyond vectors: Adapting remote sensing research for environmental monitoring with open source hardware and software: Citizen mapping the BP oil spill with balloons and kites</a>: Kite and balloon mapping is just awesome. It's kind of the OpenStreetMap for raster data.
  </li>
  <li><a href="http://2011.foss4g.org/sessions/geoglobaldomination-musical">GeoGlobalDomination: The Musical</a>: One of the highlights was the GeoGlobalDomination musical. <a href="http://vimeo.com/29203100">Grab the video</a> while it's hot.
  </li>
</ul>
<p>And of course there were also great talks from in the plenary sessions from <a href="http://twitter.com/pwramsey">Paul Ramsey</a> about <a href="http://2011.foss4g.org/sessions/why-do-you-do-exploration-open-source-business-models">Why do you do that? An exploration of open source business models</a> and <a href="http://twitter.com/schuyler">Schuyler Erle's</a> so funny lightning talk about <a href="http://2011.foss4g.org/sessions/pivoting-monetize-mobile-hyperlocal-social-gamification-going-viral">Pivoting to Monetize Mobile Hyperlocal Social Gamification by Going Viral</a>
</p>

<h3>Code Sprint</h3>

<p>At the code sprint I was working on MapQuery together with <a href="http://twitter.com/stvno">Steven Ottens</a> and <a href="http://twitter.com/h0st1le">Justin Penka</a>. Steven was working on TMS support, Justin on a 6 minutes tutorial and I on making manual adding of features possible.
</p>
<p>The OpenLayers developers did the migration from Subversion to Git for their development. OpenLayers is <a href="https://github.com/openlayers">now available</a> on Github.
</p>
<p>And luckily there was a fire alarm in between to take a <a href="http://wiki.osgeo.org/images/f/f7/Code-sprint-foss4g2011.png">group photograph</a>.
</p>

<h3>Future of the FOSS4G</h3>

<p>I really hope there won't be a yearly FOSS4G conference for the whole of the US. There should be regional events, as I think one big one would draw the attention away from the international conference. Why should you fly to Beijing for the FOSS4G 2012 if you can meet the majority of the developers in the US as well?
</p>

<h3>Final words</h3>

<p>The FOSS4G was great. It was organized well and people were always out in the evenings. The only minor nitpick is that many people working remote had the city of their company in the name badge and not the one they live in. It seems that the original for you had to fill was confusing. So for next year it should perhaps say “Location where you live”. Hence I still don't believe that there were more Dutch than German people at the conference (Tik hem aan, ouwe! ;)
</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/foss4g-2011%3A2011-09-20%3Aen%2CCouchDB%2CGeoCouch%2CMapQuery%2CErlang%2CJavaScript%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>Bolsena hacking event
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/bolsena-hacking-event-2010%3A2010-06-11%3Aen%2CCouchDB%2CJavaScript%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/bolsena-hacking-event-2010%3A2010-06-11%3Aen%2CCouchDB%2CJavaScript%2Cgeo#comments</comments>
<pubDate>Fri, 11 Jun 2010 22:35:25 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>JavaScript</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/bolsena-hacking-event-2010%3A2010-06-11%3Aen%2CCouchDB%2CJavaScript%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>The <a href="http://wiki.osgeo.org/wiki/Bolsena_Code_Sprint_2010">OSGeo hacking event in Bolsena/Italy</a> was great. Many interesting people
sitting the whole day in front of their laptops surrounded by a beautiful
scenery and nice warm sunny weather. It gets even better when you get meat for
lunch and dinner.</p>

<p>I had the chance to tell people a bit more about
<a href="http://couchdb.apache.org/">CouchDB</a> and
<a href="http://github.com/couchapp/couchapp/">Couchapps</a>,</p>

<p>One project I haven't heard that much before of was
<a href="http://deegree.org/">Degree</a>. They build the whole stack of OGC services
you could imagine. For me it was of interest that they have a
blob storage in their upcoming 3.0 release. The data
isn't flattened into SQL tables but stored as blobs. This sounds like good use
for a CouchDB backend in the future.</p>

<p>I was working with <a href="http://wiki.osgeo.org/wiki/User:Simonp">Simon Pigot</a> on a
<a href="http://geonetwork-opensource.org/">GeoNetwork</a>
re-implementation
based on CouchDB using Couchapp. We got the basic stuff like putting an XML
document into the database, editing it and returning the new document, as well
as fulltext indexing with
<a href="http://github.com/rnewson/couchdb-lucene">couchdb-lucene</a>
work. Next steps are improving the JSON to XML mapping and integrating spatial
search based on <a href="http://github.com/vmx/couchdb">GeoCouch</a>.</p>

<p>The event was really enjoyable, thanks <a href="http://couch.io/">Couchio</a> for
sponsoring the trip, thanks <a href="http://www.ticheler.net/">Jeroen</a> for
organizing it, and thanks all other hackers that made it such a awesome event.
Hope to see you next year!</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/bolsena-hacking-event-2010%3A2010-06-11%3Aen%2CCouchDB%2CJavaScript%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>Drag as long as you want
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/drag-as-long-as-want%3A2009-11-11%3Aen%2COpenLayers%2CJavaScript%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/drag-as-long-as-want%3A2009-11-11%3Aen%2COpenLayers%2CJavaScript%2Cgeo#comments</comments>
<pubDate>Wed, 11 Nov 2009 22:35:23 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>OpenLayers</category>
<category>JavaScript</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/drag-as-long-as-want%3A2009-11-11%3Aen%2COpenLayers%2CJavaScript%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>It has been a very long outstanding bug (officially it was a missing
feature) in <a href="http://www.openlayers.org/">OpenLayers</a> that annoyed
me from the first time I’ve been using OpenLayers. I’m talking about
<a href="http://trac.openlayers.org/ticket/39">ticket #39</a>: “Allow
pan-dragging while outside map until mouseup”.
</p>
<p>Normally when you drag the map in OpenLayers it will stop dragging as soon
as you hit the edge of the map viewport (the <code>div</code> that contains
the map). Whenever you have a small map, but a huge window and a loooong way to
drag, it can get quite annoying, as the maximum distance you can drag at once
is the size of that viewport.
</p>
<p>But yesterday
<a href="http://openlayers.org/pipermail/commits/2009-November/009095.html">it
finally happend</a>. A patch to fix it landed in trunk. A first rough cut was
made at the
<a href="http://openlayers.org/blog/2009/10/26/openlayers-at-the-foss4g-code-sprint/">OpenLayers
code sprint at the FOSS4G</a>.
<a href="http://wiki.osgeo.org/wiki/User:Ahocevar">Andreas Hocevar</a> reviewed
the code and made a more unobtrusive version of it (thanks, again).
</p>
<p>Try these two examples to see the difference. Click on the map an drag it a
long way to the right and back to the left again (you might need to zoom it a bit to see the full effect):
<ul>
  <li><a href="http://openlayers.org/dev/examples/lite.html">default
behaviour</a></li>
  <li><a href="http://openlayers.org/dev/examples/document-drag.html">documentDrag behaviour</a></li>
</ul>
<p>As it is a new feature, it isn’t enabled by default (and only available on
current SVN trunk, it will be available in OpenLayers 2.9). To enable it on
 your map, just use the following code to add the <code>documentDrag</code>
parameter to the
<a href="http://dev.openlayers.org/docs/files/OpenLayers/Control/DragPan-js.html">DragPan control</a> (you obviously need a recent SVN checkout).
<p><strong>Update</strong> (2009-11-18): It got even easier with
<a href="http://openlayers.org/pipermail/commits/2009-November/009109.html">r9805</a>:
</p>
<p>
  <pre>
<code>// Use default controls but with documentDrag enabled.
var controls = [
    new OpenLayers.Control.Navigation({documentDrag: true}),
    new OpenLayers.Control.PanZoom(),
    new OpenLayers.Control.ArgParser(),
    new OpenLayers.Control.Attribution()]
map = new OpenLayers.Map('map', {controls: controls});
</code></pre>
</p>
<p>For a full working version have a look at
<a href="http://svn.openlayers.org/trunk/openlayers/examples/document-drag.html">the
source of the documentDrag example</a>.
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/drag-as-long-as-want%3A2009-11-11%3Aen%2COpenLayers%2CJavaScript%2Cgeo/feed/</wfw:commentRss>
</item>
<item>
<title>Poor man’s bounding box queries with CouchDB
</title>
<link>https://vmx.cx/cgi-bin/blog/index.cgi/poor-mans-bounding-box-queries-with-couchdb%3A2009-07-19%3Aen%2CCouchDB%2CJavaScript%2Cgeo</link>
<comments>https://vmx.cx/cgi-bin/blog/index.cgi/poor-mans-bounding-box-queries-with-couchdb%3A2009-07-19%3Aen%2CCouchDB%2CJavaScript%2Cgeo#comments</comments>
<pubDate>Sun, 19 Jul 2009 22:35:27 +0200</pubDate>
<dc:creator>Volker Mische</dc:creator>
<category>en</category>
<category>CouchDB</category>
<category>JavaScript</category>
<category>geo</category>
<guid isPermaLink="false">https://vmx.cx/cgi-bin/blog/index.cgi/poor-mans-bounding-box-queries-with-couchdb%3A2009-07-19%3Aen%2CCouchDB%2CJavaScript%2Cgeo/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[

<p>
<a href="http://mail-archives.apache.org/mod_mbox/couchdb-user/200809.mbox/<gbg36q$n8g$1@ger.gmane.org>">Several</a>
<a href="http://mail-archives.apache.org/mod_mbox/couchdb-user/200903.mbox/<20090304111938.GC16406@banot.net>">people</a>
<a href="http://mail-archives.apache.org/mod_mbox/couchdb-user/200906.mbox/<2C1A5D65-F929-42B8-93CE-A9BB68C8D1DA@mac.com>">store</a>
geographical points within <a href="http://couchdb.apache.org/">CouchDB</a> and would like to make a
<a href="http://en.wikipedia.org/wiki/Minimum_bounding_rectangle">bounding box
query</a> on them. This isn’t possible with plain CouchDB
<a href="http://wiki.apache.org/couchdb/HTTP_view_API">_views</a>. But there’s
light at the end of the tunnel. One solution will be
<a href="geocouch-geospatial-queries-with-couchdb%3A2008-10-26%3Aen%2CCouchDB%2CPython%2Cgeo">GeoCouch</a>
(which can do a lot more than simple bounding box queries), once there’s a new
release, the other one is already there: you can use a the
<a href="http://wiki.apache.org/couchdb/Formatting_with_Show_and_List">list/show
API</a> (<strong>Warning</strong>: the current wiki page (as at 2009-07-19) applies to CouchDB 0.9, I use the new 0.10 API).
</p>
<p>You can either add a _list function as described in the
<a href="http://wiki.apache.org/couchdb/Formatting_with_Show_and_List">documentation</a> or use my
<a href="http://vmx.cx/cgi-bin/blog/index.cgi/list-function-editing-in-futon%3A2009-07-19%3Aen%2CCouchDB%2CJavaScript">futon-list
branch</a> which includes an interface for easier _list function creation/editing</a>.
</p>

<h3>Your data</h3>

<p>The _list function needs to match your data, thus I expect documents with
a field named <code>location</code> which contains an array with the
coordinates. Here’s a simple example document:
</p>
<p>
  <pre>
<code>
{
   "_id": "00001aef7b72e90b991975ef2a7e1fa7",
   "_rev": "1-4063357886",
   "name": "Augsburg",
   "location": [
       10.898333,
       48.371667
   ],
   "some extra data": "Zirbelnuss"
}
</code></pre>
</p>


<h3>The _list function</h3>

<p>We aim at creating a _list function that returns the same response as a
normal _view would return, but filtered with a bounding box. Let’s start
with a _list function which returns the same results as plain _view (no
bounding box filtering, yet). The whitespaces of the output differ slightly.
</p>
<p>
  <pre>
<code>function(head, req) {
    var row, sep = '\n';

    // Send the same Content-Type as CouchDB would
    if (req.headers.Accept.indexOf('application/json')!=-1)
      start({"headers":{"Content-Type" : "application/json"}});
    else
      start({"headers":{"Content-Type" : "text/plain"}});

    send('{"total_rows":' + head.total_rows +
         ',"offset":'+head.offset+',"rows":[');
    while (row = getRow()) {
        send(sep + toJSON(row));
        sep = ',\n';
    }
    return "\n]}";
};
</code></pre>
</p>

<p>The _list API allows to you add any arbitrary query string to the URL. In
our case that will be <code>bbox=west,south,east,north</code> (adapted from the
<a href="http://www.opensearch.org/Specifications/OpenSearch/Extensions/Geo/1.0/Draft_1">OpenSearch
Geo Extension</a>). Parsing the bounding box is really easy. The query
parameters of the request are stored in the property <code>req.query</code> as
key/value pairs. Get the bounding box, split it into separate values and
compare it with the values of every row.
</p>
<p>
  <pre>
<code>var row, location, bbox = req.query.bbox.split(',');
while (row = getRow()) {
    location = row.value.location;
    if (location[0]&gt;bbox[0] && location[0]&lt;bbox[2] &&
            location[1]&gt;bbox[1] && location[1]&lt;bbox[3]) {
        send(sep + toJSON(row));
        sep = ',\n';
    }
}</code></pre>
</p>
<p>And finally we make sure that no error message is thrown when the
<code>bbox</code> query parameter is omitted. Here’s the final result:
</p>
<p>
  <pre>
<code>function(head, req) {
    var row, bbox, location, sep = '\n';

    // Send the same Content-Type as CouchDB would
    if (req.headers.Accept.indexOf('application/json')!=-1)
      start({"headers":{"Content-Type" : "application/json"}});
    else
      start({"headers":{"Content-Type" : "text/plain"}});

    if (req.query.bbox)
        bbox = req.query.bbox.split(',');

    send('{"total_rows":' + head.total_rows +
         ',"offset":'+head.offset+',"rows":[');
    while (row = getRow()) {
        location = row.value.location;
        if (!bbox || (location[0]&gt;bbox[0] && location[0]&lt;bbox[2] &&
                      location[1]&gt;bbox[1] && location[1]&lt;bbox[3])) {
            send(sep + toJSON(row));
            sep = ',\n';
        }
    }
    return "\n]}";
};</code></pre>
</p>
<p>An example how to access your _list function would be:
<code>http://localhost:5984/geodata/_design/designdoc/_list/bbox/viewname?bbox=10,0,120,90&limit=10000</code>
</p>
<p>Now you should be able to filter any of your point clouds with a bounding
box. The performance should be alright for a reasonable number of points. A
usual use-case would something like displaying a few points on a map, where you
don’t want to see zillions of them anyway.
</p>
<p>Stay tuned for a follow-up posting about displaying points with
<a href="http://openlayers.org/">OpenLayers</a>.
</p>
]]></content:encoded>
<wfw:commentRss>https://vmx.cx/cgi-bin/blog/index.cgi/poor-mans-bounding-box-queries-with-couchdb%3A2009-07-19%3Aen%2CCouchDB%2CJavaScript%2Cgeo/feed/</wfw:commentRss>
</item>
</channel>
</rss>
