mirror of
https://github.com/balkian/balkian.github.com.git
synced 2024-12-25 17:58:12 +00:00
323 lines
18 KiB
HTML
323 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'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=' active' >Blog
|
|
</li></a>
|
|
|
|
<a href="../../tags/"><li class='' >Tags
|
|
</li></a>
|
|
|
|
<a href="../../cheatsheet/"><li class='' >Cheatsheets
|
|
</li></a>
|
|
|
|
<a href="../../about/"><li class='' >About
|
|
</li></a>
|
|
|
|
<a href="../../project/"><li class='' >Projects
|
|
</li></a>
|
|
|
|
<a href="//jfernando.es" target="_blank"><li>
|
|
CV
|
|
</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 “overall feeling” of each
|
|
country about each topic. Then, we used some fancy JavaScript to make
|
|
sense out of the raw information.</p>
|
|
|
|
<p>It didn’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’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’t forget to freeze your dependencies so Heroku can install them:
|
|
<code>bash pip freze > 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’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">""</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">'profile-email'</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">""</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… 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’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>
|