<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[noizZze]]></title><description><![CDATA[Ruby, Rails, Elixir and mobile development blog]]></description><link>http://noizeramp.com/</link><generator>Ghost 0.11</generator><lastBuildDate>Thu, 04 Apr 2019 12:15:13 GMT</lastBuildDate><atom:link href="http://noizeramp.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Aquarium lighting timer on Arduino ESP8266]]></title><description><![CDATA[Just when they said lights should go up and down on schedule I knew it it's not going to happen in my house. Just won't work that way.]]></description><link>http://noizeramp.com/2019/03/19/aquarium-lighting-timer-on-arduino-esp8266/</link><guid isPermaLink="false">ac0c70a0-8d4f-4b58-af49-945b0888e2ea</guid><category><![CDATA[arduino]]></category><category><![CDATA[esp8266]]></category><category><![CDATA[diy]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Tue, 19 Mar 2019 06:09:16 GMT</pubDate><content:encoded><![CDATA[<p>In this article I'd like to tell the story of building the lighting timer for my small 120 liter aquarium. Just when they said lights should go up and down on schedule I knew it it's not going to happen in my house. Just won't work that way. So I decided to automate it.</p>

<p><strong>Version 1</strong></p>

<p>Initially I built a prototype in the big plastic box. It went with the temperature sensor, LED display, power override button and two independently commutated pairs of sockets. It worked off of and old iPad power adapter. Here how it looks inside and outside:</p>

<p><img src="http://noizeramp.com/content/images/2019/03/IMG_0079-2.JPG" alt="alt"></p>

<p><img src="http://noizeramp.com/content/images/2019/03/IMG_0088_2.jpg" alt="alt"></p>

<p>As you can see, it was pretty complicated inside. Built on Android Nano V3 328. Included power-independent RTC and used the 4-relay commutation module.</p>

<p>Practice showed all that wasn't quite reliable and useful. Thermometer with one of the commutated power sockets were intended for heating circle, but then I discovered that my heating is already regulated and maintains the temperature. So that's unnecessary.</p>

<p>What's left was the timer module for the lighting. I didn't need the screen too as it's always inside the aquarium stand and no one sees it anyway. Here is where the story of the Timer v2 begins.</p>

<p><strong>Version 2</strong></p>

<p>It didn't happen immediately after I decided to rebuild my first iteration. Over the while I've got excited about ESP8266 and figured that might be a great choice for the next gen timer. It is small, working on 3.3v, allows to connect to my local network to check status and make remote switching if necessary; all in one small body.</p>

<p>Here's the schematics of what I came up with:</p>

<p><img src="http://noizeramp.com/content/images/2019/03/Aqua-Timer-2_schem-2.jpg" alt="alt"></p>

<p>220V power comes through J1 and is converted into 5V that is used to feed WeMos D1 Mini and switch the relay module. Since WeMos D1 Mini operates 3.3v, we need to use a NPN transistor as a simple switch. Traditional choice is 2N2222 with a 1kOm resistor in the base circuit to limit the current. We also need a D1 diode to cut out reverse current in the relay circuit. That's all schematically.</p>

<p>The casing was designed in Sketch Up and 3D-printed in three iterations, all due to small errors in measurements. I used PETG plastic as the material and it worked very nicely. Here's the model and the result:</p>

<p><img src="http://noizeramp.com/content/images/2019/03/Screenshot-2019-03-19-at-09.01.15.png" alt="3d model"></p>

<p><img src="http://noizeramp.com/content/images/2019/03/IMG_0089.jpg" alt="printed"></p>

<p><img src="http://noizeramp.com/content/images/2019/03/IMG_0091.jpg" alt="printed"></p>

<p>Everything mounts without screws. It's so nice to be able to print stuff in whatever dimensions you need!</p>

<p><strong>Software</strong></p>

<p>Finally, here's the software running on the board:</p>

<p><a href="https://bitbucket.org/spyromus/aqua-timer">Sources on BitBucket</a></p>]]></content:encoded></item><item><title><![CDATA[Linking ESP8266 with Arduino]]></title><description><![CDATA[<p>I found it super-hard to find meaningful info on how to link a tiny little ESP8266 (ESP-01 in my case) to an Arduino and talk to it.</p>

<h3 id="schematics">Schematics</h3>

<p>Things to notice here is power regulator 1117-33 that converts 5V of Arduino board into stable 3.3V for ESP8266. We could</p>]]></description><link>http://noizeramp.com/2017/11/29/linking-esp8266-with-arduino/</link><guid isPermaLink="false">a8784818-dac4-4a65-a432-ce75efebfc44</guid><category><![CDATA[arduino]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Wed, 29 Nov 2017 20:32:55 GMT</pubDate><content:encoded><![CDATA[<p>I found it super-hard to find meaningful info on how to link a tiny little ESP8266 (ESP-01 in my case) to an Arduino and talk to it.</p>

<h3 id="schematics">Schematics</h3>

<p>Things to notice here is power regulator 1117-33 that converts 5V of Arduino board into stable 3.3V for ESP8266. We could probably use 3.3V Arduino output, but I read it's not powerful enough for when the module is transmitting. Also I wired Arduino D11 to RXD of ESP8266 through voltage divider, so that 5V is also converted to 3.3V range. Logic level converters can be used here, but I have none handy, so divider be it.</p>

<p><img src="http://noizeramp.com/content/images/2017/11/8266-schematics.png" alt="alt"></p>

<h3 id="software">Software</h3>

<p>My module was initially in 115200 baud mode. When you don't know that it may cause a lot of confusion. Arduino I have isn't quick enough to do any useful work and catch up, so I had to find a way to switch module to a lower baud rate.</p>

<p>The module speaks AT-commands, and there are dangerous sequences that can brick your module that I won't write here to save everyone from trouble. Here's a pretty good one instead:</p>

<pre><code>AT+UART_DEF=57600,8,1,0,0
</code></pre>

<p>It switches UART into 57600 baud mode with 8 bits, 1 stop bit, 0 for parity and 0 for flow control.</p>

<p>Here's the small program that lets you talk to the module in Serial Monitor tool.</p>

<pre><code>#include &lt;SoftwareSerial.h&gt;

SoftwareSerial wifi(10, 11); // RX, TX

void setup() {  
  Serial.begin(115200);
  while (!Serial) { }

//  wifi.begin(115200);
//  wifi.println("AT+UART_DEF=57600,8,1,0,0\r\n");

  wifi.begin(57600);
  wifi.println("AT+GMR\r\n");
}

void loop() {  
  if (wifi.available()) Serial.write(wifi.read());
  if (Serial.available()) wifi.write(Serial.read());
}
</code></pre>

<h3 id="resources">Resources</h3>

<ul>
<li><a href="http://pdf.datasheet.live/datasheets-1/kec/KIA1117BF15.pdf">KIA1117 Datasheet</a></li>
<li><a href="http://rancidbacon.com/files/kiwicon8/ESP8266_WiFi_Module_Quick_Start_Guide_v_1.0.4.pdf">ESP8266 Quick Start Guide</a></li>
<li><a href="https://en.wikipedia.org/wiki/ESP8266">Wiki article on ESP8266</a></li>
</ul>]]></content:encoded></item><item><title><![CDATA[FFMPEG fade in/out expressions]]></title><description><![CDATA[Alpha expressions to help you fade in and out video elements in time.]]></description><link>http://noizeramp.com/2016/10/19/ffmpeg-fade-in-out-expressions/</link><guid isPermaLink="false">f517c50e-68c1-4e6d-a1c0-da9ae29e64b8</guid><category><![CDATA[ffmpeg]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Wed, 19 Oct 2016 19:42:31 GMT</pubDate><content:encoded><![CDATA[<p>I've been playing with FFMPEG lately mulling over a plugin for Appcelerator Titanium and figured we'll need a text rendering with nice fading in/out effect. There's text drawing filter in FFMPEG, but not a function to easily fade it, so I came up with a couple of expressions of my own. I'm working with alpha channel here, but it can easily be applied to other properties.</p>

<p><strong>Fading in</strong></p>

<p><code>alpha='if(lt(t,t1),0,(t-t1)/t2)'</code></p>

<ul>
<li><code>t1</code> - start time (in seconds),</li>
<li><code>t2</code> - length (in seconds).</li>
</ul>

<p><strong>Fading out</strong></p>

<p><code>alpha='if(lt(t,t1),1,(t2-(t-t1))/t2)'</code></p>

<ul>
<li><code>t1</code> - start time (in seconds),</li>
<li><code>t2</code> - length (in seconds).</li>
</ul>

<p><strong>Fading in and out</strong></p>

<p><code>alpha='if(lt(t,t1),0,if(lt(t,t1+t2),(t-t1)/t2,if(lt(t,t1+t2+t3),1,if(lt(t,t1+t2+t3+t4),(t4-(t-t1-t2-t3))/t4,0))))'</code></p>

<ul>
<li><code>t1</code> - fade in start time (in seconds),</li>
<li><code>t2</code> - fade in length (in seconds),</li>
<li><code>t3</code> - time to keep fully opaque (in seconds),</li>
<li><code>t4</code> - fade out length (in seconds).</li>
</ul>

<p>If you happen to know a better way or shorter expressions, please let me know.</p>]]></content:encoded></item><item><title><![CDATA[Easy options parsing in shell scripts]]></title><description><![CDATA[Simple cheat sheet on shell script option parsing using getopts.]]></description><link>http://noizeramp.com/2016/07/16/easy-options-parsing-in-shell-scripts/</link><guid isPermaLink="false">4253a0fc-e81d-4686-8c63-f9b0978e6305</guid><category><![CDATA[shell]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Sat, 16 Jul 2016 12:00:07 GMT</pubDate><content:encoded><![CDATA[<p>This is an attempt to systemize my own knowledge of options parsing in shell scripts. I mainly work in Zsh, but this is compatible with Bash and possibly others.</p>

<p>Let's assume that we want the CLI interface to look like this:</p>

<pre><code>myscript &lt;key&gt; [-v &lt;value&gt;] [-l]
</code></pre>

<p>Here we have:</p>

<ul>
<li>required option</li>
<li>two optional keys, one of which with required parameter</li>
</ul>

<p>There's a very handy tool -- <code>getopt</code> -- which handles filtering and parsing command line options. Here's how we'll use it to define optional keys:</p>

<pre><code>TEMP=`getopt lv: $@`
</code></pre>

<p>Here we set that we want to recognize only two options: <code>l</code> without arguments and <code>v</code> with one argument. Then we put whatever the script received as parameters as <code>$@</code>. The <code>getopt</code> command will set return status to <code>0</code> if parsing was successful and will return something else otherwise. We need to check if it's fine and continue, or show the usage information and exit if not:</p>

<pre><code>usage() {
  echo "USAGE: myscript &lt;key&gt; [-v &lt;value&gt;] [-l]"
  exit 1
}

if [ $? != 0 ]; then usage; fi
</code></pre>

<p>In case of success we move on. The result of <code>getopt</code> will be saved into the <code>TEMP</code> var. The way <code>getopt</code> works is it puts the recognized options first, then places <code>--</code> and finishes the string by listing everything it didn't understand.</p>

<p>Here are some examples to illustrate:</p>

<pre><code>$ getopt lv: -l
-l --

$ getopt lv: -v test
-v test --

$ getopt lv: -v test -l
-v test -l --

$ getopt lv: -v test -l xyz
-v test -l -- xyz
</code></pre>

<p>However, if you specify an unknown option, it will return the status code 1 and output an error like this:</p>

<pre><code>$ getopt lv: -v test -a
getopt: illegal option -- a
 -v test --
</code></pre>

<p>Let's parse this output. First lets put the <code>TEMP</code> into <code>$@</code> while respecting any possible quotations. </p>

<pre><code>eval set -- $TEMP
</code></pre>

<p>Next, let's go through the <code>$@</code> item by item and see what we encounter.</p>

<pre><code>for i
do
  case "$i"
  in
    -l)
      echo "Found -l option"
      shift;;

    -v)
      echo "Found -v option with parameter '$2'"
      shift 2;;

    --)
      shift;
      break;
  esac
done
</code></pre>

<p>As you can see, it all is pretty easy to grasp. Two things to notice:</p>

<pre><code>for i
do
done
</code></pre>

<p>is basically equivalent to:</p>

<pre><code>for i in "$@"
do
done
</code></pre>

<p>And the second is that after <code>eval set -- $TEMP</code> we have everything in our <code>TEMP</code> var assigned to <code>$@</code> and the first nine arguments to <code>$1</code> through <code>$9</code>. So first argument is in <code>$1</code>. When we iterate over the <code>$@</code>, we pick the first item, find the matching branch in case statement, act on it, then <strong>shift</strong> whatever number of arguments we consumed out of <code>$@</code> and run another cycle. The exit condition is finding <code>--</code> (in which case we also shift it out, in case we need the remainder).</p>

<p>Now that you know what this <code>shift</code> command does, let's recall that we wanted to have the required first argument. Here's the piece we should put at the very beginning after the usage function definition.</p>

<pre><code>if [ $# -lt 1 ]; then usage; fi
key=$1
shift 1
</code></pre>

<p>It checks if we have enough arguments, picks the first one and shifts it out in preparation to optional arguments parsing.</p>

<p>Here's the full version of the script:</p>

<pre><code>usage() {
  echo "USAGE: myscript &lt;key&gt; [-v &lt;value&gt;] [-l]"
  exit 1
}

if [ $# -lt 1 ]; then usage; fi
key=$1
shift 1

TEMP=`getopt lv: $@`
if [ $? != 0 ]; then usage; fi

setting=0

for i
do
  case "$i"
  in
    -l)
      echo "Found -l option"
      shift;;

    -v)
      echo "Setting value of '$key' to '$2'"
      setting=1
      shift 2;;

    --)
      shift;
      break;
  esac
done

if [ $setting -eq 0 ]; then
  echo "Reading value of '$key'"
fi
</code></pre>

<p>Go ahead and try it:</p>

<pre><code>$ ./myscript
$ ./myscript test
$ ./myscript test -v value
$ ./myscript test -l
</code></pre>]]></content:encoded></item><item><title><![CDATA[Elixir meets Docker.io]]></title><description><![CDATA[Detailed recipe of how to build your app Docker image and run it efficiently.]]></description><link>http://noizeramp.com/2016/07/16/elixir-meets-docker-io/</link><guid isPermaLink="false">3dc498a9-eb30-48ab-b99b-6c3480d55a55</guid><category><![CDATA[elixir]]></category><category><![CDATA[docker]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Sat, 16 Jul 2016 06:46:58 GMT</pubDate><content:encoded><![CDATA[<p>In usual conditions it's preferable to deploy your Elixir / Erlang apps with <code>exrm</code> and a-la Capistrano derivatives like <code>edeliver</code>. There are cases when you either need to make it easily installable or handable to a client. In this rare cases packaging the app in the Docker image is worth the effort.</p>

<p>Here is how my <code>Dockerfile</code> looks:</p>

<pre><code># Dockerfile
FROM trenpixster/elixir:1.3.0

# Install AWS client (optional)
RUN apt-get update
RUN apt-get install -y awscli

RUN adduser --quiet deploy
WORKDIR /home/deploy

# Copy the app
COPY . app
RUN chown -R deploy:deploy app
WORKDIR app

USER deploy
ENV MIX_ENV prod

# This is to make sure it doesn't ask for Hex and Rebar
RUN mix local.hex --force
RUN mix local.rebar --force

# Build the release
RUN mkdir -p priv/static
RUN mix do deps.get, phoenix.digest
RUN touch config/prod.exs

# Prepare data directory
RUN mkdir -p /home/deploy/data/mnesia

EXPOSE 8080
EXPOSE 8443
VOLUME /home/deploy/data
ENTRYPOINT ["mix", "do", "compile,", "phoenix.server"]
</code></pre>

<p>Let's go section by section and I explain what's going on.</p>

<p><strong>Base image</strong>. To create a runable Docker image I pick either official Elixir image (<a href="https://hub.docker.com/_/elixir/">elixir</a>) or the one by <em>trenpixter</em> (<a href="https://hub.docker.com/r/trenpixster/elixir/">trenpixter/elixir</a>). The last one tends to be very slightly ahead of the official.</p>

<pre><code># Dockerfile
FROM trenpixster/elixir:1.3.0
</code></pre>

<p><strong>APT packages</strong>. If you need any system packages, you can install them as you usually would. Here I install AWS CLI package that I use to store backups to AWS S3.</p>

<pre><code># Install AWS client (optional)
RUN apt-get update
RUN apt-get install -y awscli
</code></pre>

<p><strong>User setup</strong>. You obviously need a user that will run the app. Traditionally, I call it <code>deploy</code>, but it can be anything.</p>

<pre><code>RUN adduser --quiet deploy
WORKDIR /home/deploy
</code></pre>

<p><strong>Placing sources</strong>. Now the fun part begins. We need to get sources of the app into the box. I don't use any git repositories or anything for this, just copy sources from my working folder into the image.</p>

<pre><code># Copy the app
COPY . app
RUN chown -R deploy:deploy app
WORKDIR app
</code></pre>

<p>There are some files and directories that I don't want to be copied over and so I put them in a <code>.dockerignore</code> file that sits in the root of my local project tree:</p>

<pre><code># .dockerignore
.git
Dockerfile*
d-build
_build
deps
rel
Mnesia*
test
</code></pre>

<p>This one is typical, so you can grab it and add your own lines as necessary. Moving on.</p>

<p><strong>Building the release</strong>. Now that the environment and sources are all ready we switch the user to the one that will be running the app and set the environment variable to production:</p>

<pre><code>USER deploy
ENV MIX_ENV prod
</code></pre>

<p>This little hack is to make sure the building phase doesn't ask to install / update Hex and Rebar interactively. You certainly can't answer that.</p>

<pre><code># This is to make sure it doesn't ask for Hex and Rebar
RUN mix local.hex --force
RUN mix local.rebar --force
</code></pre>

<p>Finally, we create a directory for assets, fetch dependencies and build the app as part of the Phoenix static assets digesting. </p>

<pre><code># Build the release
RUN mkdir -p priv/static
RUN mix do deps.get, phoenix.digest
RUN touch config/prod.exs
</code></pre>

<p>The last line in the block above deserves some explanation. In this particular app I pass env variables to the app during the container launch. These vars customize behavior of the app and are part of the app configuration. If I don't touch the script, it won't be reconsidered during the app start and the app won't pick up new var values.</p>

<p><strong>Launch configuration</strong>. In this app I use Mnesia database and as logic suggests, its data should be stored outside the box to survive the restarts and crashes. For this purpose I create a directory inside the user home <code>/home/deploy/data</code> that I then expose to the Docker environment as VOLUME. This volume will be mounted during the container start to a location in the host environment. Either default location Docker chooses for you, or your specific one.</p>

<p>Finally, I tell to expose two ports and specify the entry point that will be run when the container with this image launches -- <code>mix do compile, phoenix.server</code>:</p>

<pre><code># Prepare data directory
RUN mkdir -p /home/deploy/data/mnesia

EXPOSE 8080
EXPOSE 8443
VOLUME /home/deploy/data
ENTRYPOINT ["mix", "do", "compile,", "phoenix.server"]
</code></pre>

<hr>

<p><strong>Running the image</strong></p>

<p>Here's how I run the image:</p>

<pre><code>docker run --name myapp \
  -td \
  --restart=unless-stopped \
  -p 80:8080 \
  -p 443:8443 \
  -v /home/alg/volumes/myapp:/home/deploy/data \
  -e APP_VAR="1234" \
  image
</code></pre>

<ul>
<li>I tell Docker to run this container with the name <code>myapp</code>. </li>
<li>It should be a detached TTY (we obviously want it to run in background). </li>
<li>It should be restarted upon crashes until explicitly stopped.</li>
<li>I bind ports 8080 and 8443 that this container provides to my host's 80 and 443, so that whatever app runs in it is exposed to the outside.</li>
<li>The volume <code>/home/deploy/data</code> that was defined in the Docker file is bound to the host's directory <code>/home/alg/volumns/myapp</code>.</li>
<li>I pass an environment var <code>APP_VAR</code> to the container. This var is used in the app.</li>
<li>And finally, here's the name of the image we built with that <code>Dockerfile</code> above.</li>
</ul>

<p>Have fun!</p>]]></content:encoded></item><item><title><![CDATA[Cross-platform app links]]></title><description><![CDATA[Notes on making app links work for Android and iOS with XML/JSON samples and Titanium snippets.]]></description><link>http://noizeramp.com/2016/05/23/cross-platform-app-links/</link><guid isPermaLink="false">3cdcbfbb-4fb5-465b-bb8b-a58619a2677b</guid><category><![CDATA[android]]></category><category><![CDATA[iOS]]></category><category><![CDATA[titanium]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Mon, 23 May 2016 06:11:50 GMT</pubDate><content:encoded><![CDATA[<p>Here are some notes after the recent research into deep linking into the apps. The goal was to launch the app on clicks on links in email. Traditionally, we were using a custom scheme to register the app as a handler for, but this didn't work quite well. So notes:</p>

<ul>
<li>Don't use custom schemes. Links with custom schemes are no longer clickable in SMS, Chrome and Gmail on Android.</li>
<li>Use http / https schemes with your app domains. If your domains have "well-known" asset link files, your app is offered as the default handler. (Verification pending)</li>
</ul>

<hr>

<h4 id="quickstartandroid">Quick start -- Android</h4>

<ul>
<li>Register intent-filter for your activity. Here we tell that this app can handle HTTP and HTTPS links to <code>my.domain.com</code> with paths starting with <code>/app</code>.</li>
</ul>

<pre><code class="language-xml">&lt;android&gt;  
  &lt;manifest&gt;
    &lt;application&gt;
      &lt;activity ...&gt;
        &lt;intent-filter&gt;
          &lt;action android:name="android.intent.action.MAIN"/&gt;
          &lt;category android:name="android.intent.category.LAUNCHER"/&gt;
        &lt;/intent-filter&gt;
        &lt;intent-filter&gt;
          &lt;action android:name="android.intent.action.VIEW"/&gt;
          &lt;category android:name="android.intent.category.DEFAULT"/&gt;
          &lt;category android:name="android.intent.category.BROWSABLE"/&gt;
          &lt;data android:scheme="https" /&gt;
          &lt;data android:scheme="http" /&gt;
          &lt;data android:host="my.domain.com" /&gt;
          &lt;data android:pathPrefix="/app"/&gt;
        &lt;/intent-filter&gt;
      &lt;/activity&gt;
    &lt;/application&gt;
  &lt;/manifest&gt;
&lt;/android&gt;  
</code></pre>

<ul>
<li>Put the app links verification file to the web server at <code>my.domain.com/.well-known/assetlinks.json</code>. This is only necessary if you want your app offered for that domain name links handling by default. If you can live with it just being offered along with Chrome or other browsers, that's fine to leave it out.</li>
</ul>

<pre><code class="language-json">{ relation: [ "delegate_permission/common.handle_all_urls" ],
  target: {
    namespace: "android_app",
    package_name: "com.noizeramp.myapp",
    sha256_cert_fingerprints: [
      "14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
    ] }
}
</code></pre>

<p>You get fingerprint from <code>$ keytool -list -v -keystore my-release-key.keystore</code></p>

<ul>
<li>Add in-app handling of the event (Titanium version).</li>
</ul>

<pre><code class="language-javascript">Ti.App.Android.launchIntent.getData()  
</code></pre>

<hr>

<h4 id="quickstartios">Quick start -- iOS</h4>

<ul>
<li>Register entitlements. Put the details into the <code>MyApp.entitlements</code> file:</li>
</ul>

<pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;  
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;  
&lt;plist version="1.0"&gt;  
&lt;dict&gt;  
  &lt;key&gt;com.apple.developer.associated-domains&lt;/key&gt;
  &lt;array&gt;
    &lt;string&gt;applinks:my.domain.com&lt;/string&gt;
  &lt;/array&gt;
&lt;/dict&gt;  
&lt;/plist&gt;  
</code></pre>

<ul>
<li>Put the app links verification file to the web server. Here we tell that we allow the app with this appID to handle paths starting with <code>/app</code> on this domain. The app links verification file should be placed at <code>my.domain.com/apple-app-site-association</code> or <code>my.domain.com/.well-known/apple-app-site-association</code>.</li>
</ul>

<pre><code class="language-json">applinks: {  
  apps: [],
  details: [
    { appID: "675aasd9f8.com.noizeramp.myapp",
      paths: [ "/app/*" ] }
  ]
}
</code></pre>

<ul>
<li>Add in-app handling (Titanium version).</li>
</ul>

<pre><code class="language-javascript">if (OS_IOS) {  
  Ti.App.iOS.addEventListener('continueactivity', function(e){
    // This is important hack for 5.2.x (until 5.4.0). This createUserActivity
    // call that is never exectured is needed for the compiler to know we are
    // interested in continueactivity event.
    if (e.activityType === "never-executed") {
      Ti.App.iOS.createUserActivity();
    }

    if (e.activityType === "NSUserActivityTypeBrowsingWeb"){
      onOpen(e.webpageURL);
    }
  });
}
</code></pre>

<hr>

<h4 id="linksofinterest">Links of interest</h4>

<ul>
<li><p>iOS</p>

<ul><li><a href="https://developer.apple.com/library/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html">https://developer.apple.com/library/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html</a></li>
<li>Appcelerator Titanium SDK 5.2.0 broke <code>continueactivity</code> event delivery, and so we need a hack. The fix is to be delivered in SDK 5.4.0. Related issue -- <a href="https://jira.appcelerator.org/browse/TIMOB-20220">https://jira.appcelerator.org/browse/TIMOB-20220</a></li></ul></li>
<li><p>Android</p>

<ul><li><a href="https://developer.android.com/training/app-links/index.html">https://developer.android.com/training/app-links/index.html</a></li>
<li><a href="https://developer.android.com/guide/topics/manifest/intent-filter-element.html">https://developer.android.com/guide/topics/manifest/intent-filter-element.html</a></li>
<li><a href="https://developer.android.com/guide/topics/manifest/data-element.html">https://developer.android.com/guide/topics/manifest/data-element.html</a></li></ul></li>
</ul>]]></content:encoded></item><item><title><![CDATA[Filtering ListView in NativeScript]]></title><description><![CDATA[Simple and easy to grasp example of how one would filter a ListView in NativeScript.]]></description><link>http://noizeramp.com/2016/04/02/filtering-listview-in-nativescript/</link><guid isPermaLink="false">3d018a06-a0b2-495d-a5f4-cd52cff14119</guid><category><![CDATA[nativescript]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Fri, 01 Apr 2016 21:28:19 GMT</pubDate><content:encoded><![CDATA[<p>Here's how you filter a list. </p>

<pre><code class="language-xml">&lt;!-- demo.xml --&gt;  
&lt;Page navigatingTo="navigatingTo"&gt;  
  &lt;StackLayout orientation="vertical"&gt;
    &lt;TextField text="{{ filter }}" hint="Enter filter"/&gt;
    &lt;ListView items="{{ items }}" /&gt;
  &lt;/StackLayout&gt;
&lt;/Page&gt;  
</code></pre>

<p>This is a very basic page with a ListView component that is supposed to list string values and a TextField that we'll use for filtering purposes.</p>

<pre><code class="language-javascript">// demo.js
var DemoModel = require("./demo-model");

exports.navigatingTo = function(e) {  
  var page = e.object;
  page.bindingContext = new DemoModel();
};
</code></pre>

<p>In the controller we create an instance of the model (see below) and bind it to a pange.</p>

<pre><code class="language-javascript">// demo-model.js
var Observable = require("data/observable").Observable;  
var _ = require("lodash");

module.exports = function() {  
  var model = new Observable();

  model.allItems = [ "Jack", "John", "Mark", "Ashley" ];
  model.items    = _refilter();
  model.filter   = "";

  function _refilter() {
    var items = model.allItems;
    var filter = model.filter.trim();

    if (filter) {
      var regexp = new RegExp(filter, 'i');
      items = _.filter(items, function(i) {
        return i.match(regexp);
      });
    }

    return items;
  }

  model.on(Observable.propertyChangeEvent, function(e) {
    if (e.propertyName === "filter") model.set("items", _refilter());
  });

  return model;
};
</code></pre>

<p>Our model is an instance of <code>Observable</code>. In <code>allItems</code> we hold the original list, <code>items</code> property is what we actually render, and <code>filter</code> holds current filter string. The only function -- <code>_refilter</code> -- creates a new list out of the original basing on the current filter value. We call it initially, and every time the <code>filter</code> property changes.</p>

<p>Simple enough.</p>]]></content:encoded></item><item><title><![CDATA[Understanding NativeScript binding patterns]]></title><description><![CDATA[NativeScript has one terrific, yet sometimes misunderstood, feature -- data bindings. In this post I would like to lay it out so that it's easy to grasp and start using.]]></description><link>http://noizeramp.com/2016/04/01/understanding-nativescript-binding/</link><guid isPermaLink="false">29861e81-0625-4eab-9411-c8c3a7609a27</guid><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Fri, 01 Apr 2016 20:56:06 GMT</pubDate><content:encoded><![CDATA[<p>NativeScript has one terrific, yet sometimes misunderstood, feature -- data bindings. In this post I would like to lay it out so that it's easy to grasp and start using.</p>

<h4 id="frommodeltoview">From Model to View</h4>

<p>Let's take this simple XML template consisting of just one field.</p>

<pre><code class="language-xml">&lt;!-- demo.xml --&gt;  
&lt;Page loaded="loaded"&gt;  
  &lt;Label text="{{ name }}" /&gt;
&lt;/Page&gt;  
</code></pre>

<p>It has a page with the <code>loaded</code> event handler bound to the co-named method of the controller and a single label with the text bound to the property of the page context named <code>name</code>.</p>

<pre><code class="language-javascript">// demo.js

var model = { name: "NativeScript };

exports.loaded = function(e) {  
  var page = e.object;
  page.bindingContext = model;
};
</code></pre>

<p>This is a really simple controller. The <code>loaded</code> method is called when the XML page is loaded. The single argument is an event object. The <code>object</code> property points to the source of event -- this page. The most important part here is the assignment of the <code>model</code> to <code>page.bindingContext</code>. This is how you pass the context to the XML view. This is how you tell what the <code>name</code> is in your template. Easy.</p>

<h4 id="fromviewtomodel">From View to Model</h4>

<p>Now that we know how to display data from controller in the view, let's pass the data back.</p>

<pre><code class="language-xml">&lt;!-- demo2.xml --&gt;  
&lt;Page loaded="loaded"&gt;  
  &lt;StackLayout orientation="vertical"&gt;
    &lt;TextField text="{{ firstName }}" /&gt;
    &lt;Button text="Save" tap="save" /&gt;
  &lt;/StackLayout&gt;
&lt;/Page&gt;  
</code></pre>

<p>Slightly more complex template with two components arranged vertically. The text field linked to the <code>firstName</code> context (model) property and the button that calls exported <code>save</code> method on tap.</p>

<pre><code class="language-javascript">// demo2.js
var model = { firstName: "Mark" };

exports.loaded = function(e) {  
  var page = e.object;
  page.bindingContext = model;
};

exports.save = function(e) {  
  alert(model.firstName);
};
</code></pre>

<p>Here the <code>save</code> handler is of interest. We don't look up the view and don't query its <code>text</code> property. Instead, we pick the current value from the model. NativeScript keeps the property in the model in sync with the view. When you change it in code, the view updates. When the user types something new in the view, the model in memory changes (and property change events are fired).</p>

<h4 id="fromcontrollertocontrollerforward">From Controller to Controller (forward)</h4>

<p>Now it's turn to understand how do you pass data from one controller to the next. Let's assume that we have two pages -- an index list of items and the details view.</p>

<pre><code class="language-xml">&lt;!-- index.xml --&gt;  
&lt;Page loaded="loaded"&gt;  
  &lt;ListView items="{{ items }}" itemTap="onItemSelected"&gt;
    ...
  &lt;/ListView&gt;
&lt;/Page&gt;  
</code></pre>

<p>We'll use a list view to display items. I don't go into the details of the view implementation. All you need to know is that the list view calls <code>itemTap</code> handler every time you tap on an item in the list.</p>

<pre><code class="language-javascript">// index.js

exports.loaded = function(e) {  
  var page = e.object;

  var items = [
    { id: 1, name: "Apples" },
    { id: 2, name: "Grapes" }
  ];

  page.bindingContext = {
    items: items
  };
};

exports.onItemSelected = function(e) {  
  var itemView = e.object;

  // Item is going to be one of the items from the list
  // that we bound to the list view:
  // { id: 1, name: "Apples" }, or
  // { id: 2, name: "Grapes" }
  var item = itemView.bindingContext;

  Frame.topmost().navigate({
    moduleName: './details',
    context: item
  });
};
</code></pre>

<p>We setup items list as an array of items with some data. When the list view is rendered, every item view in the list is assigned its own <code>bindingContext</code> (just like the one we assign to the page in the <code>loaded</code> handler.) It's done automatically by the list view component.</p>

<p>When an item is tapped, <code>ListView</code> calls a method bound to <code>itemTap</code> property and passes the item view in the object property of the event. This view has the item it renders in the binding context. In our case it is one of two hashes (with names "Apples" or "Grapes").</p>

<p>We take the item from the <code>bindingContext</code> and pass it on to the details view as that view context. Look how elegantly have we passed the tapped item to the details controller. You an pass any data to controllers this way.</p>

<pre><code class="language-javascript">// details.js

exports.loaded = function(e) {  
  var page = e.object;

  // Get the context passed to this controller by the previous one:
  // In our case: { id: x, name: y }
  var item = page.navigationContext;

  page.bindingContext = item;
};
</code></pre>

<p>The details controller is very simple. It takes the context that we sent to it (tapped item) and assigns it to the binding context of the page, so that the view could access the <code>id</code> and <code>name</code> properties. You aren't limited to this, of course. For example, you could use <code>item.id</code> to load more data.</p>

<h4 id="sendingdatabackfromcontrollertotheparentcontroller">Sending data back from Controller to the parent Controller</h4>

<p>Sometimes we need to return some results from the controller. For example, when you select an avatar from a gallery, or a country from a list in a separate controller and then bring the selection back to the previous screen. How do we pass the results back?</p>

<p>The answer lies in the context again. </p>

<pre><code class="language-javascript">// first.js

var model = {};

exports.navigatingTo = function(e) {  
  if (e.isBackNavigation) {
    // returning from the second.js
    alert(model.result);
  } else {
    // entering this controller initially
  }
};

export.onGotoSecond = function() {  
  Frame.topmost().navigate({
    moduleName: './second',
    context: model
  });
};
</code></pre>

<p>Instead of the <code>loaded</code> handler we use <code>navigatingTo</code> handler that is called earlier, before the page is loaded, and contains the <code>isBackNavigation</code> flag that is set to TRUE when we are returning from the later controller back to this one.</p>

<p>It's not important when the <code>onGotoSecond</code> is called. It can be a button touch or some other event. When we navigate to the second screen we pass our <code>model</code> as the context and expect to see the result in it. This trick works since in JavaScript data is passed by references, not values. For us it means that whatever changes the second controller makes to the model we pass to it, the first controller "sees."</p>

<pre><code class="language-javascript">// second.js

var model = null;

exports.loaded = function(e) {  
  var page = e.object;
  model = page.navigationContext;
};

exports.onSubmit = function() {  
  model.result = "the result of this screen";
  Frame.topmost().goBack();
};
</code></pre>

<p>Here in the second controller, we save navigation context into own <code>model</code> variable, and upon the <code>onSubmit</code> event, set the <code>result</code> property of it to something useful. When going back, we get into the <code>e.isBackNavigation === true</code> branch of the first controller's <code>navigatingTo</code> handler and can work on the results.</p>

<p>Hope this intro to practical data binding patterns was helpful.</p>]]></content:encoded></item><item><title><![CDATA[Dash docset for NativeScript]]></title><description><![CDATA[Release notes for the NativeScript Dash Docset.]]></description><link>http://noizeramp.com/2016/03/31/dash-docset-for-nativescript/</link><guid isPermaLink="false">05dc5ec6-401d-4d9e-b00c-1b6429dd108a</guid><category><![CDATA[nativescript]]></category><category><![CDATA[dash]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Thu, 31 Mar 2016 19:03:41 GMT</pubDate><content:encoded><![CDATA[<p>If you are developer and using Mac, you must absolutely know offline documentation and snippets browser <a href="https://kapeli.com/dash">Dash</a> by now. If not, go check it out. It will change your life.</p>

<p>This morning I submitted my own docset for <a href="http://nativescript.org">NativeScript 1.7.1</a>. It's been accepted later today and can be found in <code>Preferences -&gt; Downloads -&gt; User Contributed</code>. Search for "NativeScript".</p>

<p>I'm planning on adding How-to's and guides from the official documentation site in it in the upcoming release.</p>]]></content:encoded></item><item><title><![CDATA[Global data sync in Android apps]]></title><description><![CDATA[This post contains some insights into how global and user-specific sync works in Android apps. Highlights some poorly documented areas of the process.]]></description><link>http://noizeramp.com/2015/04/03/global-data-sync-in-android-apps/</link><guid isPermaLink="false">6d2806f3-d3aa-4cff-9ee6-0827f58ae805</guid><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Fri, 03 Apr 2015 10:07:45 GMT</pubDate><content:encoded><![CDATA[<p>I'm currently working on an app that needs to sync both global and user-specific data. In this post I'd like to highlight some poorly documented areas of the process.</p>

<p>Let's start with the list of bits we'll need for a successful sync:</p>

<ul>
<li><p><em>ContentProvider</em>. Even if you don't use content providers, you'll need one, or the whole thing will crash on you.</p></li>
<li><p><em>Authenticator and a binding service</em>. Sync framework uses authenticators to manage user account tokens. Even if you don't need user account to access global app data, you need an authenticator. Let it be a no-op empty thing.</p></li>
<li><p><em>Sync adapter and a binding service</em>. This is the heart of it. Every time the sync is needed, the <code>onPerform</code> method is called.</p></li>
</ul>

<p>You may have noticed that:</p>

<ul>
<li><p>We need binding services for authenticator and sync adapter. The services are the entry points for the sync framework and other apps (if you choose to allow that).</p></li>
<li><p>We still need an account for an account-independent sync. If you look at other apps, like Shazam that require similar syncs, you'll notice they have a "Sync" account hardwired in Settings -> Accounts -> &lt;App name&gt;</p></li>
</ul>

<p>Next, let's look at the steps. There's a <a href="https://developer.android.com/training/sync-adapters/index.html">great class by Google</a> that you can follow to get your basic setup ready. Here's what you will do:</p>

<ul>
<li>Create a no-op content provider</li>
<li>Create a no-op authenticator and its binding service, declare it in the manifest</li>
<li>Create an empty sync adapter with its binding service, declare it in the manifest</li>
</ul>

<p>A couple of things that puzzled me at this point:</p>

<ul>
<li><p>Account type (as seen in <code>xml/authenticator.xml</code>, <code>xml/syncadapter.xml</code> and <code>MainActivity</code>) is the identifier of the sync account. You tie together sync adapter with authenticator and account with it.</p></li>
<li><p>Authority (as seen in <code>xml/syncadapter.xml</code> and provider definition in manifest). This is a link between the content provider and the rest of the world. At the very least, every sync adapter is linked to a specific content provider through the authority identifier.</p></li>
</ul>

<h2 id="creatinguseraccount">Creating user account</h2>

<p>In Google class it is shown how the sync account is added through the <code>AccountManager</code>. What's missing is the explanation of how to deal with the edge cases.</p>

<ul>
<li>During every app start, when you setup sync account, you need to check if the account with your account type is already present. If it is, you just use that account, and not even attempt adding a new one. Here's the bit of code:</li>
</ul>

<pre><code class="language-java">AccountManager accountManager = AccountManager.get(this);  
Account[] accounts = accountManager.getAccountsByType(ACCOUNT_TYPE_GLOBAL);  
if (accounts.length &gt; 0) {  
    globalSyncAccount = accounts[0];
} else {
    Account newAccount = new Account(ACCOUNT_GLOBAL, ACCOUNT_TYPE_GLOBAL);
    ...
    // add new account and init (see below)
}
</code></pre>

<ul>
<li>When you are adding an account, you may want to configure it on the spot. Sync framework operates on per-account basis, which means that you need to configure an <em>account</em> if you want to enable periodic updates etc. Here's how it's done:</li>
</ul>

<pre><code class="language-java">if (accountManager.addAccountExplicitly(newAccount, null, null)) {  
    // registered new account, save it
    globalSyncAccount = newAccount;

    // Configure automatic account updates
    ContentResolver.setIsSyncable(globalSyncAccount, AUTHORITY_GLOBAL, 1);
    ContentResolver.setSyncAutomatically(globalSyncAccount, AUTHORITY_GLOBAL, true);
    ContentResolver.addPeriodicSync(globalSyncAccount, AUTHORITY_GLOBAL, Bundle.EMPTY, 60 * 60);
} else {
    // failed to register
    globalSyncAccount = null;
}
</code></pre>

<h2 id="forcingsynconappstart">Forcing sync on app start</h2>

<p>Basically, you don't do this. Following the traditional approach deeply ingrained in my mind, I tried to make it work and succeeded, but somewhere along the way I've got an understanding that in most cases this is completely unnecessary. The reason for that is periodic updates. You can configure your global data account to be updated (roughly) once an hour or once a day (depending on how frequently your data changes) and the system will perform the updates even when the app isn't running. Which means that you literally have the most recent data whenever your app starts.</p>

<p>To get laser-precise with updates, you can use GCM to get an invisible to user notifications when the backend changes data. Your app will be able to seamlessly update itself in the background in the most energy-friendly fashion (sync framework keeps an eye on when it's the best time to run syncs, batches them and does the rest to save energy).</p>

<p>If you still absolutely need to update on launch, go ahead and send a manual sync request. Just note that in some cases, you may encounter that your syncs run twice in a row. The exact nature of this effect is still unclear, but it looks like happening if you request a sync from the <code>Application.onCreate()</code> method. Moving it to main activity's <code>onCreate()</code> solved the problem (watch out for orientation changes which trigger this method -- you don't want to send a sync request every time the user turns their device).</p>

<h2 id="whatsnext">What's next?</h2>

<p>Next I'll be working on integrating user-specific syncs. This will get much more curious since it's a two-way street.</p>]]></content:encoded></item><item><title><![CDATA[Chat rooms app in Elixir in 15 minutes]]></title><description><![CDATA[Showcase post that touches a tiny part of what Elixir and the accompanying tooling can help you build in very short time. Covers Phoenix and Websockets.]]></description><link>http://noizeramp.com/2014/12/18/chat-rooms-in-elixir-in-15-minutes/</link><guid isPermaLink="false">70424a59-1e6a-42d7-abd2-3ea6f67f60b6</guid><category><![CDATA[elixir]]></category><category><![CDATA[phoenix]]></category><category><![CDATA[websockets]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Thu, 18 Dec 2014 10:55:00 GMT</pubDate><content:encoded><![CDATA[<p>This is the showcase post that touches a tiny part of what Elixir and the accompanying tooling can help you build in very little time.</p>

<h1 id="thegoal">The goal</h1>

<p>In this post we are going to build a very simple chat app with multiple rooms. Anyone with the link will be able to connect and say something. We won't be storing the history of messages for the case of simplicity.</p>

<p>If you are lost, or just want to skip over some hoops, the <a href="https://github.com/alg/chatex">source of the app</a> we build here is available at Github.</p>

<h1 id="preparations">Preparations</h1>

<p>This walkthrough will require Elixir 1.0.2+ as a dependency for Phoenix Framework. Please install it before you start.</p>

<p>Get the latest Phoenix Framework.</p>

<pre><code>$ git clone https://github.com/phoenixframework/phoenix.git &amp;&amp; cd phoenix &amp;&amp; git checkout v0.6.2 &amp;&amp; mix do deps.get, compile
</code></pre>

<p>Create a new phoenix app. This creates a new app that is configured to use Phoenix Framework. You don't need the phoenix folder that was checked out of the repo in the previous step.</p>

<pre><code>$ mix phoenix.new chatex ~/tmp/chatex
</code></pre>

<p>Compile and launch your app skeleton.</p>

<pre><code>$ cd ~/tmp/chatex
$ mix do deps.get, compile
$ mix phoenix.start
</code></pre>

<p>You should see the root page at <a href="http://localhost:4000/">http://localhost:4000/</a> now.</p>

<h1 id="layoutsandassets">Layouts and assets</h1>

<p>When we created a Phoenix app, the mix task initialized directory structure for us:</p>

<ul>
<li><code>config</code> folder is for your config files</li>
<li><code>lib</code> is for standalone library code</li>
<li>Static files go into the <code>priv</code> directory (much like <code>public</code> in Rails)</li>
<li><code>test</code> folder has familiar to Rails developers structure for tests</li>
<li><code>web</code> folder contains your web application code (much list <code>app</code> in Rails)</li>
</ul>

<p>Throw in <a href="http://code.jquery.com/jquery-2.1.1.min.js">jquery-2.1.1.min.js</a> and <a href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js">bootstrap.min.js</a> (3.3.1) into <code>priv/static/js</code> and <a href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">bootstrap.min.css</a> into <code>priv/static/css</code>.</p>

<p>Update the layout <code>web/templates/layout/application.html.eex</code> to include our new assets and clean up a bit. Here's what I got:</p>

<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
    &lt;meta name="description" content=""&gt;
    &lt;meta name="author" content=""&gt;

    &lt;title&gt;Chatex&lt;/title&gt;
    &lt;link rel="stylesheet" href="/css/bootstrap.min.css"&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div class="container"&gt;
      &lt;%= @inner %&gt;
    &lt;/div&gt;

    &lt;script type="text/javascript" src="/js/jquery-2.1.1.min.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" src="/js/bootstrap.min.js"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>If you are familiar with Rails layouts, you should be at home with the notion of inserting generated pages inside the broader layout file. Here we have <code>&lt;%= @inner %&gt;</code> marking the place where the generated page content goes.</p>

<h1 id="routing">Routing</h1>

<p>Open the <code>web/router.ex</code> file. What you see shouldn't be terribly hard to comprehend. You can read more on routes in <a href="http://www.phoenixframework.org/v0.6.2/docs/routing">officinal Routing guide</a>. Let's just define three routes.</p>

<pre><code>scope "/", Chatex do
  pipe_through :browser
  get "/",    RoomsController, :show
  get "/:id", RoomsController, :show
  post "/message/:room_id", MessagesController, :create, as: :new_message
end
</code></pre>

<h1 id="controllers">Controllers</h1>

<p>Let's add <code>Chatex.RoomsController</code>:</p>

<pre><code>defmodule Chatex.RoomsController do
  use Phoenix.Controller

  @default_room "Lobby"

  @doc "shows a specific room with room_id specified"
  def show(conn, %{ "id" =&gt; room_id }) do
    conn |&gt; render_room room_id
  end

  @doc "shows a default room -- Lobby"
  def show(conn, _params) do
    conn |&gt; render_room @default_room
  end


  # renders the room with given ID
  defp render_room(conn, room_id) do
    conn |&gt; render :show, room_id: room_id
  end

end
</code></pre>

<p>We add two <code>show</code> clauses -- one for the default room and one for the room with ID.</p>

<p>You can read more about controllers in the <a href="http://www.phoenixframework.org/v0.6.2/docs/controllers">official controllers guide</a>.</p>

<p>With that out of the way, let's move to views. We will get back to controllers when sending actual messages.</p>

<h1 id="views">Views</h1>

<p>Views are slightly different from what we've seen in Rails. They consist of two parts -- presenter module and templates. Read more on views in the <a href="http://www.phoenixframework.org/v0.6.2/docs/views">official views guide</a> and <a href="http://www.phoenixframework.org/v0.6.2/docs/templates">templates guide</a>.</p>

<p>For now we'll create an empty view module <code>web/views/rooms_view.ex</code>:</p>

<pre><code>defmodule Chatex.RoomsView do
  use Chatex.View
end
</code></pre>

<p>And then create the template for the show action:</p>

<pre><code>&lt;div class="row"&gt;
  &lt;div class="col-sm-4"&gt;
    &lt;h2&gt;Rooms&lt;/h2&gt;
    &lt;ul id="rooms"&gt;
      &lt;li&gt;&lt;a href="&lt;%= Chatex.Router.Helpers.lobby_path(:show) %&gt;"&gt;Lobby&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href="&lt;%= Chatex.Router.Helpers.room_path(:show, "Help") %&gt;"&gt;Help&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
  &lt;div class="col-sm-8"&gt;
    &lt;h1&gt;&lt;%= @room_id %&gt;&lt;/h1&gt;
    &lt;div id="chatbox"&gt;&lt;/div&gt;

    &lt;div id="chatline"&gt;
      &lt;form class="form" action="&lt;%= Chatex.Router.Helpers.new_message_path(:create, @room_id) %&gt;"&gt;
        &lt;input type="hidden" name="room_id" id="room_id" value="&lt;%= @room_id %&gt;"&gt;
        &lt;div class="form-group"&gt;
          &lt;div class="row"&gt;
            &lt;div class="col-sm-4"&gt;
              &lt;input type="text" name="user" id="user" placholder="User name" class="form-control"/&gt;
            &lt;/div&gt;
            &lt;div class="col-sm-7"&gt;
              &lt;input type="text" name="body" id="body" placholder="Message" class="form-control"/&gt;
            &lt;/div&gt;
            &lt;div class="col-sm-1"&gt;
              &lt;input type="submit" class="btn btn-default" value="Say" /&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</code></pre>

<p>If you restart your app at this point, you should be able to change pages by clicking on the Lobby and Help in the sidebar.</p>

<h1 id="channels">Channels</h1>

<p>We will need some interactivity in the app. Phoenix Framework comes with built-in WebSockets and PubSup support, which are super fun to work with.</p>

<p>First, we define the channel in the routes and mount it on the <code>/ws</code> path:</p>

<pre><code>defmodule Chatex.Router do
  use Phoenix.Router
  use Phoenix.Router.Socket, mount: "/ws"

  channel "messages", Chatex.MessagesChannel

  # ...
end
</code></pre>

<p>Second, let's create the <code>web/channel/messages_channel.ex</code> that will be talking to the WebSockets clients:</p>

<pre><code>defmodule Chatex.MessagesChannel do
  use Phoenix.Channel

  @doc "Called when the user connects to the room."
  def join(socket, _room_id, _message) do
    { :ok, socket }
  end

  @doc "Called when the user disconnects."
  def leave(socket, _message) do
    socket
  end

end
</code></pre>

<p>This is a bare bones channel that does literally nothing. It accepts connections to any rooms and does nothing when a user leaves.</p>

<p>On the client side, we need to create a JavaScript file <code>priv/static/js/room.js</code> and include it in the layout file along with <code>/js/phoenix.js</code> after jQuery and Bootstrap.</p>

<pre><code>$(function() {
  // new message form submission handler
  var form = $("form");
  form.on("submit", function(e) {
    e.preventDefault();

    var url  = form.attr('action'),
        body = $("#body"),
        user = $("#user");

    $.post(url, { message: { user: user.val(), body: body.val() } }, function(data) {
      body.val('').focus();
    });
  });

  // connection to the channel
  var socket = new Phoenix.Socket("/ws");
  socket.join("messages", $("#room_id").val(), {}, function(channel) {
    channel.on("new:message", function(data) {
      var div = $("&lt;div class='alert alert-info'&gt;&lt;/div&gt;").text(data.user + " said: " + data.body);
      $("#chatbox").append(div);
    });
  });
});
</code></pre>

<p>Here we listen for form submissions and then sending <code>message[user]</code> and <code>message[body]</code> to the <code>MessagesController#create</code>. We also connect to the room topic via WebSocket and listen for new messages to display.</p>

<p>Now let's create <code>MessagesController</code> that will broadcast our message to the members of the same room.</p>

<pre><code>defmodule Chatex.MessagesController do
  use Phoenix.Controller

  plug :action

  @doc "Broadcasts a message to the members of the #room_id."
  def create(conn, %{ "room_id" =&gt; room_id, "message" =&gt; %{ "user" =&gt; user, "body" =&gt; body } }) do
    Phoenix.Channel.broadcast "messages", room_id, "new:message", %{ user: user, body: body }
    conn |&gt; text "ok" 
  end

end
</code></pre>

<p>The controller handles the POST request to create a message in a certain room by broadcasting it to all users in the "messages" channel listening to topic with the ID of the room.</p>

<p>Try restarting the app, opening several browsers windows (some in the same room, some in different) and test how messages are delivered.</p>

<h1 id="testing">Testing</h1>

<p>In this demo app I completely ignored the testing aspect of development for the sake of time and space. Testing deserves a separate series of posts. It's vast territory.</p>

<h1 id="exercisestoconsider">Exercises to consider</h1>

<ul>
<li>Try using <code>phoenix_haml</code> instead of <code>Eex</code></li>
<li>Think about how could you list the history of 10 last entered rooms in the sidebar instead of static links</li>
<li>Do you think you can create a separate channel that will send <code>:new_room</code> messages whenever someone enters a new room and then update the sidebar list of rooms dynamically?</li>
<li>How about treating rooms as hashtags (#lobby), and broadcast messages to listeners of all hashtags found in a message ("#lobby and #help users, hello!")?</li>
<li>Can you sanitize room id so that it allows only alphanumerics and dashes?</li>
</ul>

<h1 id="conclusion">Conclusion</h1>

<p>We haven't even scratched the surface of what's possible in Elixir and Phoenix Framework, but I hope you've got an idea of how simple it is to build interactive web apps with them.</p>

<p>The general idea is that it's not a request-response infrastructure, like Rails. Your application gears are <em>always</em> spinning. You can have long running processes with progress reported, lengthy calculations, real-time games, dynamic interfaces and much more. All of this sits on the base of reliable multi-core-ready foundation with supervisors, processes, self-recovery and native tools for distribution, scaling and monitoring.</p>

<p>Have fun! Any comments or questions are welcome.</p>]]></content:encoded></item><item><title><![CDATA[Bare bones files watch]]></title><description><![CDATA[Detailed explanation of bare bones file watcher without any dependencies.]]></description><link>http://noizeramp.com/2014/12/08/bare-bones-files-watch/</link><guid isPermaLink="false">60437f45-8958-4f9b-872d-1f4435ae8783</guid><category><![CDATA[shell]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Mon, 08 Dec 2014 10:27:22 GMT</pubDate><content:encoded><![CDATA[<p>Sometimes I just need to follow the changes to files and act upon that. There are plenty of "watchers" out there, like <a href="https://github.com/guard/guard">Guard</a> and <a href="https://github.com/mynyml/watchr">Watchr</a>, but if I really don't want to drag the bag of gems, here's what I do:</p>

<pre><code>#!/bin/zsh

typeset -a pids

tidy()  
{
    for pid in $pids
    do
        kill $pid

    done
}

trap tidy INT

(fswatch -e '#' lib test web | xargs -I anything -R 1 -L 1 -t mix test)&amp;
pids=($!)

(fswatch -0 src/coffee | xargs -0 -n 1 -I _ sh -c "cat src/coffee/* | coffee --compile --stdio &gt; priv/static/js/application.js")&amp;
pids+=$!

wait
</code></pre>

<p>The original is by Dave Thomas and was posted in an <a href="https://groups.google.com/forum/#!topic/elixir-lang-talk/PaLYrQeZrek">Elixir user group thread</a>.</p>

<p>We define a function that will terminate our background tasks on INT signal, then start two watchers and add their PIDs to the list. Finally, we wait.</p>

<p>Now to the <code>fswatch</code> command syntax. (Mac OS X users can install this tool with <code>brew install fswatch</code>.) The tool is pretty handy. It watches for changes in the given file / directory and sends notifications. In the first example, we just watch for notifications in code directories and run <code>mix test</code> for each noticed change. In the second, we watch for changes in <code>src/coffee</code> and then run the CoffeeScript compiler along with concatenation of the files.</p>

<p>Easy, bare bones and plenty of opportunities. Explore.</p>]]></content:encoded></item><item><title><![CDATA[YAML you may have never known]]></title><description><![CDATA[A small collection of handy YAML tips you may have never known.]]></description><link>http://noizeramp.com/2014/10/23/yaml-you-may-have-never-known/</link><guid isPermaLink="false">8b97b650-1b18-4601-bce7-be3a7f6f6f0b</guid><category><![CDATA[yaml]]></category><category><![CDATA[rails]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Thu, 23 Oct 2014 12:51:54 GMT</pubDate><content:encoded><![CDATA[<p><strong>HTML and multiline strings</strong></p>

<p>Storing HTML in YAML fields in a pretty way has never been as easy.</p>

<pre><code>info: &gt;  
  &lt;h1&gt;Page title&lt;/h1&gt;

  &lt;p&gt;Some paragraph text.&lt;/p&gt;
</code></pre>

<p><em>NOTE: You'll still need to tell Rails it's safe HTML.</em></p>

<p><strong>Arrays and hashes</strong></p>

<p>This is useful when you keep the list of options. For example, for the <code>&lt;select&gt;</code> tags.</p>

<pre><code>options:  
  "yes": "Yes"
  "no":  "No"
  maybe: Maybe
</code></pre>

<p><em>NOTE: YAML interprets "yes" as <code>true</code> and "no" as <code>false</code> case-insensitively, that's why we need to put them in quotes</em></p>

<p>And this is how you'd use them in Rails:</p>

<pre><code>= select_tag :field, options_for_select(I18n.t('options').invert)
</code></pre>

<p><em>NOTE: We need to invert the Hash so that keys and values land where Rails expects them.</em></p>

<p>If you don't care about key-value mapping, options can be stored as:</p>

<pre><code>options: [ "Yes", "No", "Maybe" ]  
</code></pre>

<p>or</p>

<pre><code>options:  
  - "Yes"
  - "No"
  - Maybe
</code></pre>

<p><em>NOTE: Quotes again.</em></p>

<p>Using this version in Rails is as easy, no inversion though:</p>

<pre><code>= select_tag :field, options_for_select(I18n.t('options'))
</code></pre>]]></content:encoded></item><item><title><![CDATA[My current Elixir toolkit]]></title><description><![CDATA[All my free time I'm spending on a my own project that I decided to write in Elixir, Rails and CoffeeScript. Here's the run down of tooling I use.]]></description><link>http://noizeramp.com/2014/10/19/my-current-elixir-toolkit/</link><guid isPermaLink="false">d7f8d76a-81f4-4d5a-89e2-9b3413bb090d</guid><category><![CDATA[elixir]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Sun, 19 Oct 2014 18:18:07 GMT</pubDate><content:encoded><![CDATA[<p>All my free time I'm spending on a my own project that I decided to write in Elixir, Rails and CoffeeScript. There is the service backend that runs heavily multi-threaded and so Elixir / Erlang was a natural choice.</p>

<p>I figure some of my friends might be interested in the tools I use currently, so here's the short rundown:</p>

<p><strong>Release management</strong> - <a href="https://github.com/bitwalker/exrm">exrm</a></p>

<p>Fantastic tool for building releases ready for the deployment. Prepares a versioned nicely packed archive with all dependencies and start / stop / restart / remote_console scripts.</p>

<p><strong>JSON handling</strong> - <a href="https://github.com/talentdeficit/jsex">jsex</a></p>

<p>Sweet little library for encoding, decoding and jumping through all sorts of hoops with JSON.</p>

<p><strong>Websockets</strong> - <a href="https://github.com/sockjs/sockjs-erlang/">sockjs-erlang</a></p>

<p>Although there's great variety of web servers in Erlang Kingdom, I  chose this one for my own needs for its simplicity. It sits on top of <a href="https://github.com/ninenines/cowboy">Cowboy</a> and provides a very nice interface, so you focus on the task not on the Websocket handling chores.</p>

<p><strong>UUID</strong> - <a href="https://github.com/zyro/elixir-uuid">uuid</a></p>

<p>Tiny library for all sorts of UUID generation.</p>

<p><strong>HTTP client</strong> - <a href="https://github.com/edgurgel/httpoison">httpoison</a></p>

<p>As with web servers, and basically everything else, there are plenty of options, but the one I stuck with is Httpoison. Being based on HTTPotion, it's an excellent piece of software that makes running HTTP requests async or not a breeze.</p>

<p>These are basically the essentials I spent time finding. Hope it saves a bit of time for some of you.</p>]]></content:encoded></item><item><title><![CDATA[Completes and totals, or how to count]]></title><description><![CDATA[Quick into into how to write conditional counts without sub-selects in Postgresql.]]></description><link>http://noizeramp.com/2014/10/14/completes-and-totals-or-how-to-count/</link><guid isPermaLink="false">4f2a12b8-2b34-49d5-a8b8-7772bc490c0f</guid><category><![CDATA[sql]]></category><dc:creator><![CDATA[Aleksey Gureev]]></dc:creator><pubDate>Tue, 14 Oct 2014 10:28:07 GMT</pubDate><content:encoded><![CDATA[<p>In every third project I see SQL like this:</p>

<pre><code>SELECT
  (SELECT COUNT(*)
   FROM table 
   WHERE group_id = X AND completed = 1) as completed,

  (SELECT COUNT(*)
   FROM table
   WHERE group_id = X) as total

FROM table
WHERE group_id = X
GROUP BY group_id
</code></pre>

<p>As you might understand the intention is to count all records in the group and those with <code>completed</code> flag set. This solution gives me creeps.</p>

<p>Here's how I would write the same:</p>

<pre><code>SELECT
  COUNT(NULLIF(completed, 0)) as completed,
  COUNT(*) as total
FROM table
WHERE group_id = X
</code></pre>

<p>Now pick your DB book and go read what <code>NULLIF</code> function is, and do me a favor. No more crazy subselects, ok?</p>]]></content:encoded></item></channel></rss>