You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
18 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Balkian&#39;s site - WELCOME</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="../../font-awesome/css/all.css">
<link rel="stylesheet" media="only screen" href="../../css/main.css">
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300|Comfortaa' rel='stylesheet' type='text/css'>
</head>
<body>
<div id="container" class="container">
<div id="contentwrapper">
<div id="content">
<header id="header">
<ul class="navbar" id="navbar">
<a href="../../">
<li >
<i class="fa fa-home fa-large"></i>
</li></a>
<a href="../../post/"><li class='' >Blog
</li></a>
<a href="../../tags/"><li class='' >Tags
</li></a>
<a href="../../cheatsheet/"><li class='' >Cheatsheets
</li></a>
<a href="../../page/about/"><li class='' >About
</li></a>
<a href="../../project/"><li class='' >Projects
</li></a>
<a href="../../page/todo/"><li class='' >To-do
</li></a>
<a href="//jfernando.es" target="_blank"><li>
CV
</li></a>
<a href="../../search"><li>
<i class="fa fa-search"></i>
</li></a>
</ul>
</header>
<h2>Updating EuroLoveMap</h2>
<span class="date">2014/03/27</span>
<span>
<a class="tag" href='../../tags/javascript'><span class="label">javascript</span></a>
<a class="tag" href='../../tags/python'><span class="label">python</span></a>
<a class="tag" href='../../tags/heroku'><span class="label">heroku</span></a>
</span>
<h3></h3>
<p>As part of the <a href="http://www.opener-project.org/2013/07/18/opener-hackathon-in-amsterdam/">OpeNER
hackathon</a>
we decided to build a prototype that would allow us to compare how
different countries feel about several topics. We used the OpeNER
pipeline to get the sentiment from a set of newspaper articles we
gathered from media in several languages. Then we aggregated those
articles by category and country (using the source of the article or the
language it was written in), obtaining the &ldquo;overall feeling&rdquo; of each
country about each topic. Then, we used some fancy JavaScript to make
sense out of the raw information.</p>
<p>It didn&rsquo;t go too bad, it turns out <a href="http://eurosentiment.eu/wp-content/uploads/2013/07/BOLv9qnCIAAJEek.jpg">we
won</a>.</p>
<p>Now, it was time for a face-lift. I used this opportunity to play with
new technologies and improve it:</p>
<ul>
<li>Using Flask, this time using python 3.3 and Bootstrap 3.0</li>
<li>Cool HTML5+JS cards (thanks to
<a href="http://pastetophone.com">pastetophone</a>)</li>
<li>Automatic generation of fake personal data to test the interface</li>
<li>Obfuscation of personal emails</li>
</ul>
<p>The result can be <a href="http://eurolovemap.herokuapp.com/">seen here</a>.</p>
<h2 id="publishing-a-python-3-app-on-heroku">Publishing a Python 3 app on Heroku</h2>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
<table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">mkvirtualenv -p /usr/bin/python3.3 eurolovemap</code></pre></td></tr></table>
</div>
</div>
<p>Since Heroku uses python 2.7 by default, we have to tell it which
version we want, although it supports python 3.4 as well. I couldn&rsquo;t
get python 3.4 working using the
<a href="https://launchpad.net/~fkrull/+archive/deadsnakes">deadsnakes</a> ppa, so
I used python 3.3 instead, which works fine but is not officially
supported. Just create a file named <em>runtime.txt</em> in your project root,
with the python version you want to use:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
<table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">python-3.3.1</code></pre></td></tr></table>
</div>
</div>
<p>Don&rsquo;t forget to freeze your dependencies so Heroku can install them:
<code>bash pip freze &gt; requirements.txt</code></p>
<h2 id="publishing-personal-emails">Publishing personal emails</h2>
<p>There are really sophisticated and effective ways to obfuscate personal
emails so that spammers cannot easily grab yours. However, this time I
needed something really simple to hide our emails from the simplest form
of crawlers. Most of the team are in academia somehow, so in the end all
our emails are available in sites like Google Scholar. Anyway, nobody
likes getting spammed so I settled for a custom <a href="http://en.wikipedia.org/wiki/Caesar_cipher">Caesar
cipher</a>. Please, don&rsquo;t use
it for any serious application if you are concerned about being spammed.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
<table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">1
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">2
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">blur_email</span>(email):
<span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;&#34;</span><span style="color:#f92672">.</span>join([chr(ord(i)<span style="color:#f92672">+</span><span style="color:#ae81ff">5</span>) <span style="color:#66d9ef">for</span> i <span style="color:#f92672">in</span> email])</code></pre></td></tr></table>
</div>
</div>
<p>And this is the client side:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">
<table style="border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-javascript" data-lang="javascript"><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 1
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 2
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 3
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 4
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 5
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 6
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 7
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 8
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79"> 9
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">10
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">11
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">12
</span><span style="margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7c7c79">13
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-javascript" data-lang="javascript">window.<span style="color:#a6e22e">onload</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span>(){
<span style="color:#a6e22e">elems</span> <span style="color:#f92672">=</span> document.<span style="color:#a6e22e">getElementsByClassName</span>(<span style="color:#e6db74">&#39;profile-email&#39;</span>);
<span style="color:#66d9ef">for</span>(<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">e</span> <span style="color:#66d9ef">in</span> <span style="color:#a6e22e">elems</span>){
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">blur</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">elems</span>[<span style="color:#a6e22e">e</span>].<span style="color:#a6e22e">innerHTML</span>;
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">email</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;</span>;
<span style="color:#66d9ef">for</span>(<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">s</span> <span style="color:#66d9ef">in</span> <span style="color:#a6e22e">blur</span>){
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">a</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">blur</span>.<span style="color:#a6e22e">charCodeAt</span>(<span style="color:#a6e22e">s</span>)
<span style="color:#a6e22e">email</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">email</span><span style="color:#f92672">+</span>String.<span style="color:#a6e22e">fromCharCode</span>(<span style="color:#a6e22e">a</span><span style="color:#f92672">-</span><span style="color:#ae81ff">5</span>);
}
<span style="color:#a6e22e">elems</span>[<span style="color:#a6e22e">e</span>].<span style="color:#a6e22e">innerHTML</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">email</span>;
}
}
</code></pre></td></tr></table>
</div>
</div>
<p>Unfortunately, this approach does not hide your email from anyone using
<a href="http://phantomjs.org/">PhantomJS</a>,
<a href="http://zombie.labnotes.org/">ZombieJS</a> or similar. For that, other
approaches like generating a picture with the address would be
necessary. Nevertheless, it is overkill for a really simple ad-hoc
application with custom formatting and just a bunch of emails that would
easily be grabbed manually.</p>
<h2 id="generation-of-fake-data">Generation of fake data</h2>
<p>To test the contact section of the site, I wanted to populate it with
fake data. <a href="https://github.com/joke2k/faker">Fake-Factory</a> is an amazing
library that can generate fake data of almost any kind: emails,
association names, acronyms&hellip; It even lets you localise the results
(get Spanish names, for instance) and generate factories for certain
classes (à la Django).</p>
<p>But I also wanted pictures, enter <a href="http://lorempixel.com/">Lorem Pixel</a>.
With its API you can generate pictures of almost any size, for different
topics (e.g. nightlife, people) and with a custom text. You can even use
an index, so it will always show the same picture.</p>
<p>For instance, the picture below is served through Lorem Pixel.</p>
<p><img src="http://lorempixel.com/400/200/nightlife/" alt="" /></p>
<p>By the way, if you only want cat pictures, take a look at
<a href="http://placekitten.com/">Placekitten</a>. And for NSFW text, there&rsquo;s the
<a href="http://slipsum.com/">Samuel L. Jackson Ipsum</a></p>
</div>
<div id="sidebar" class="fixed">
<div id="badge" class="flip-container" ontouchstart="this.classList.toggle('hover');">
<div class="flipper sticky">
<div class="front">
<img id="avatar" src="../../img/me.png">
</div>
<div class="back">
<img id="picture" src="../../img/me-bat.png">
</div>
</div>
</div>
<div id="about">
<div class="icons">
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fab fa-inverse fa-stack-1x fa-linux"></i></span><span class="explanation">Linux user</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fab fa-inverse fa-stack-1x fa-android"></i></span><span class="explanation">Android dev and user</span></span>
<a href="http://github.com/balkian" target="_blank"><span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fab fa-inverse fa-stack-1x fa-github"></i> </span><span class="explanation">Github user</span></span></a>
<a href="http://gitlab.com/balkian" target="_blank"><span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fab fa-inverse fa-stack-1x fa-gitlab"></i> </span><span class="explanation">GitLab user</span></span></a>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fab fa-inverse fa-stack-1x fa-stack-exchange"></i> </span><span class="explanation">StackExchange fan</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fas fa-inverse fa-stack-1x fa-music"></i> </span><span class="explanation">Music lover</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fas fa-inverse fa-stack-1x fa-film"></i> </span><span class="explanation">Movie fan</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fas fa-inverse fa-stack-1x fa-laptop"></i> </span><span class="explanation">Always on a PC</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fas fa-inverse fa-stack-1x fa-moon"></i> </span><span class="explanation">Night owl</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fas fa-inverse fa-stack-1x fa-terminal"></i></span> <span class="explanation">CLI user</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fas fa-inverse fa-stack-1x fa-flag"></i></span> <span class="explanation">I love languages</span></span>
<span class="coolicon"><span class="fa-stack"> <i class="fas fa-square fa-stack-2x" ></i><i class="fas fa-inverse fa-stack-1x fa-code"></i> </span> <span class="explanation">I love programming</span></span>
</div>
</div>
<div class="entries">
<h2 class="title">Latest entries</h2>
<dt><a href="../../post/2019-01-06-zigbee2mqtt/">Controlling Zigbee devices with MQTT</a></dt>
<a class="tag" href='../../tags/mqtt'><span class="label">mqtt</span></a>
<a class="tag" href='../../tags/iot'><span class="label">iot</span></a>
<a class="tag" href='../../tags/zigbee'><span class="label">zigbee</span></a>
<dt><a href="../../post/2016-09-28-tqdm/">Progress bars in python</a></dt>
<a class="tag" href='../../tags/python'><span class="label">python</span></a>
<dt><a href="../../post/2015-04-10-github-dotfiles/">Sharing dotfiles</a></dt>
<a class="tag" href='../../tags/github'><span class="label">github</span></a>
<a class="tag" href='../../tags/git'><span class="label">git</span></a>
<a class="tag" href='../../tags/dotfiles'><span class="label">dotfiles</span></a>
<dt><a href="../../post/2014-12-09-zotero/">Zotero</a></dt>
<a class="tag" href='../../tags/zotero'><span class="label">zotero</span></a>
<a class="tag" href='../../tags/webdav'><span class="label">webdav</span></a>
<a class="tag" href='../../tags/nginx'><span class="label">nginx</span></a>
<a class="tag" href='../../tags/apache'><span class="label">apache</span></a>
</div>
</div>
<div class="clear"></div>
</div>
<footer class="pagefooter" role="contentinfo">
<div class="contact">
<p>
J. Fernando Sánchez Rada | balkian
</p>
</div>
<ul id="social">
<li><a href="http://github.com/balkian"><i class="fab fa-github"></i></a></li>
<li><a href="http://lab.gsi.upm.es/balkian"><i class="fab fa-gitlab"></i></a></li>
<li><a href="http://twitter.com/balkian"><i class="fab fa-twitter"></i></a></li>
<li><a href="http://git.sinpapel.es/balkian"><i class="fab fa-git"></i></a></li>
<li><a href="http://linkedin.com/in/jfsanchezrada"><i class="fab fa-linkedin"></i></a></li>
</ul>
<p>
<i class="fab fa-creative-commons"></i> Creative Commons A-SA-NC
</p>
</footer>
</div>
<script src="../../js/jquery-2.0.2.min.js"></script>
</body>
</html>