<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Andrea Franz</title>
    <description></description>
    <link>http://gravityblast.com/</link>
    <atom:link href="http://gravityblast.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 10 Dec 2024 08:56:59 +0000</pubDate>
    <lastBuildDate>Tue, 10 Dec 2024 08:56:59 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>NFT built-in Swap Market with gasless listing</title>
        <description>&lt;p&gt;More than a year ago I was working on a &lt;a href=&quot;https://github.com/status-im/keycard-redeem&quot;&gt;Token Redeem dApp&lt;/a&gt;
for the &lt;a href=&quot;https://keycard.tech/&quot;&gt;Keycard Hardware Wallet&lt;/a&gt; that supported both &lt;strong&gt;ERC20&lt;/strong&gt; and &lt;strong&gt;ERC721&lt;/strong&gt; tokens.
While working on that I had the idea of adding some &lt;strong&gt;gamification&lt;/strong&gt; to a standard &lt;strong&gt;ERC721 contract&lt;/strong&gt;:
something similar to what I used to do when I was younger, &lt;strong&gt;swapping NBA cards with friends&lt;/strong&gt; to collect all the players of my favourite team.&lt;/p&gt;

&lt;p&gt;If we think of the full collection of those cards as an ERC721 collection, the players’ team can be thought as a &lt;strong&gt;trait type&lt;/strong&gt; of
that NFT.&lt;/p&gt;

&lt;p&gt;There are many platforms that allow &lt;strong&gt;to buy and sell NFTs&lt;/strong&gt;, but what I wanted to add was a way to be able to &lt;strong&gt;list my cards
without paying gas&lt;/strong&gt;, and to &lt;strong&gt;swap them atomically&lt;/strong&gt; with other cards with some &lt;strong&gt;specific traits I like&lt;/strong&gt;, to include them in my collection.&lt;/p&gt;

&lt;p&gt;If all or some of the &lt;strong&gt;traits are on chain&lt;/strong&gt;, it’s easy to implement a swap with some kind of &lt;strong&gt;trait validation&lt;/strong&gt;.
And anyone can list their cards simply using a signature,
following the same pattern as the one used in the &lt;a href=&quot;https://eips.ethereum.org/EIPS/eip-2612&quot;&gt;EIP-2612 permit&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;Moreover, we can add some &lt;strong&gt;swap rules&lt;/strong&gt; in the &lt;a href=&quot;https://eips.ethereum.org/EIPS/eip-712&quot;&gt;EIP-721 message&lt;/a&gt; that validate
the swap based on the traits I like.&lt;/p&gt;

&lt;h2 id=&quot;example&quot;&gt;Example:&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Alice has card &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; both with trait &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; and she wants a card with trait &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; &lt;strong&gt;OR&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;She signs a message that says: “card &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; can be swapped with any card with trait &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; &lt;strong&gt;OR&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt;”.&lt;/li&gt;
  &lt;li&gt;The message and signature can be saved on a centralized server or shared by Alice with friends.&lt;/li&gt;
  &lt;li&gt;Bob receives the signature and sends it with a transaction to the contract specifying the id of the cards he wants to swap.&lt;/li&gt;
  &lt;li&gt;The contract checks if Bob’s card is either a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt;, and swap the cards atomically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule can be a simple bitstring like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0001&lt;/code&gt; (swappable only with trait A)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0011&lt;/code&gt; (swappable only with trait A &lt;strong&gt;or&lt;/strong&gt; B)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1011&lt;/code&gt; (swappable only with trait A, B, &lt;strong&gt;or&lt;/strong&gt; D)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I like this idea because it adds more dynamics for collectors, even if it can be very specific to each project and cannot really be
used as a standard. Nevertheless, I decided to start a new &lt;a href=&quot;https://cybertarotnft.com&quot;&gt;project&lt;/a&gt; to test it,
together with my friend and favourite artist &lt;a href=&quot;https://twitter.com/ROYB_Art&quot;&gt;Royb&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For both of us this has been a side project, and therefore it took many months to be completed,
but in this long journey we learnt a lot and finally we are happy to announce that this new idea will be launched soon!&lt;/p&gt;

&lt;h2 id=&quot;cybertarot-nft&quot;&gt;CyberTarot NFT&lt;/h2&gt;

&lt;p&gt;When he joined the team, Royb was working on some artwork inspired by the Tarot Major Arcana cards, so we decided to build our project along
the same lines as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Tarot_card_games&quot;&gt;Tarot Cards Games&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This initial concept was conceived with special focus on the Art itself and on the Swap Market in order to convey some initial level of gamification,
while leaving the development of a full game for the future,
hopefully by sponsoring people from the community to contribute to it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/cyber-tarot/cyber-tarot-2.jpg&quot; alt=&quot;Cyber Tarot Drawings&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/cyber-tarot/cyber-tarot-3.jpg&quot; alt=&quot;Cyber Tarot Drawings&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We named it &lt;a href=&quot;https://cybertarotnft.com&quot;&gt;CyberTarot&lt;/a&gt;, and Royb started producing some amazing work,
with more than 450 drawings that together built a collection of 580 unique traits and 10K
CyberTarot Minor Arcana.&lt;/p&gt;

&lt;p&gt;Each one of these Minor Arcana, amongst its many traits, has &lt;strong&gt;a rank and a suit&lt;/strong&gt; based on the token id.
And since the token id is available to the &lt;strong&gt;Swap Market&lt;/strong&gt;,
they can be used as &lt;strong&gt;swap rules&lt;/strong&gt; as described above.
By swapping cards, collectors will be able to create &lt;strong&gt;mini decks&lt;/strong&gt; with cards ranked from 0 to 9,
or &lt;strong&gt;royal&lt;/strong&gt; mini decks if they follow the same suit.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/cyber-tarot/CyberTarotNFT-full.gif&quot; alt=&quot;Cyber Tarot Preview&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The second phase of the project will be the deployment of the &lt;strong&gt;22&lt;/strong&gt; fractionalized
Major Arcana, whose shares can be minted only by owning a &lt;strong&gt;mini deck&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/cyber-tarot/cyber-tarot-1.jpg&quot; alt=&quot;Cyber Tarot Drawings&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We hope that this project is well received by the NFT community.
Our goal has been to make it innovative and different from the usual PFPs,
by adding much more diversification and value to the art,
as well as by introducing gamification dynamics that we are really excited to see in action soon.&lt;/p&gt;

&lt;p&gt;If this project has gotten you excited like we are,
please share this post and follow/share our &lt;a href=&quot;https://twitter.com/CyberTarotNFT&quot;&gt;CyberTarotNFT Twitter account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to collaborate and help build a community around the CyberTarot, &lt;a href=&quot;https://twitter.com/gravityblast&quot;&gt;please slide in my DM&lt;/a&gt; :).&lt;/p&gt;

&lt;p&gt;happy hacking.&lt;/p&gt;
</description>
        <pubDate>Mon, 22 Nov 2021 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2021/11/22/nft-built-in-swap-market-with-gasless-listing/</link>
        <guid isPermaLink="true">http://gravityblast.com/2021/11/22/nft-built-in-swap-market-with-gasless-listing/</guid>
        
        <category>nft</category>
        
        <category>ethereum</category>
        
        <category>smart-contracts</category>
        
        
      </item>
    
      <item>
        <title>Signed request query string with Elixir</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://github.com/gravityblast/signed_request&quot;&gt;SignedRequest&lt;/a&gt; is a simple &lt;a href=&quot;http://elixir-lang.org/&quot;&gt;Elixir&lt;/a&gt; module created to
sign request query strings using &lt;a href=&quot;https://en.wikipedia.org/wiki/Hash-based_message_authentication_code&quot;&gt;HMAC&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app-1&lt;/code&gt; generates a page with a list of images dynamically generated by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app-2&lt;/code&gt;.
Something like:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://app-2.local/generate-image?type=png&amp;amp;size=200&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
  ...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;URL&lt;/code&gt; of that image is viewable by users, this means that someone can maliciously open that link and change the size parameter
to a big number, making &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app-2&lt;/code&gt; blow up.&lt;/p&gt;

&lt;p&gt;Instead of adding validations for each parameter we receive in the query string, we can just sign the request so that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app-2&lt;/code&gt; knows that the url has been generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;by app-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Both apps share the same secret key:&lt;/p&gt;
&lt;div class=&quot;language-elixir highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:signed_request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:secret_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;SECRET-KEY-SHARED-BY-BOTH-APPS&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app-1&lt;/code&gt; uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SignedRequest.SignedURI&lt;/code&gt; to sign the query string:&lt;/p&gt;
&lt;div class=&quot;language-elixir highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:png&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;size:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;query_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignedRequest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SignedURI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The generated query string contains now a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sig&lt;/code&gt; parameter:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;sig=addebd2454bded3770f09fe7bcd979e41b108385d80e02771734ab37e8b25641&amp;amp;size=200&amp;amp;type=png&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app-2&lt;/code&gt; can now decode the query string and validate the signature:&lt;/p&gt;
&lt;div class=&quot;language-elixir highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignedRequest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SignedURI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;do_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:invalid_hmac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;render_404&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 08 May 2017 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2017/05/08/signed-request-query-string-with-elixir/</link>
        <guid isPermaLink="true">http://gravityblast.com/2017/05/08/signed-request-query-string-with-elixir/</guid>
        
        <category>elixir</category>
        
        <category>phoenix</category>
        
        <category>signed-request</category>
        
        
      </item>
    
      <item>
        <title>Build and restart your Go web app with Fresh</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://github.com/gravityblast/fresh&quot;&gt;Fresh&lt;/a&gt; is a command line tool that builds and (re)starts your web application everytime you save a Go file.&lt;/p&gt;

&lt;p&gt;I usually use tests when I add/change some features in my application, so I don’t need to refresh the browser to check if everything works.
But when I change simple things, or maybe some templates, I need to stop the server, build and restart. It’s not a big deal since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go build&lt;/code&gt; is really fast,
but I wanted to automate this process with Fresh.&lt;/p&gt;

&lt;p&gt;Instead of running the application directly, I run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fresh&lt;/code&gt; inside the app folder. Every time I create/modify/delete a file, Fresh runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go build&lt;/code&gt; and restarts the application.
If the build command returns an error, it will log the error message in the tmp folder. If the framework you are using supports Fresh, it can show that error in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/gravityblast/traffic&quot;&gt;Traffic&lt;/a&gt; already supports it. If you run a Traffic app with Fresh, Traffic automatically add a Middleware that
shows the build errors if an error log file exists.&lt;/p&gt;

&lt;p&gt;Anyway Fresh is not part of Traffic, and you can use it with any other framework that supports some kind of middleware.&lt;/p&gt;

&lt;p&gt;In the &lt;a href=&quot;https://github.com/gravityblast/fresh/tree/master/_examples&quot;&gt;_example&lt;/a&gt; folder there is an example app using &lt;a href=&quot;https://github.com/codegangsta/martini&quot;&gt;Martini&lt;/a&gt;
where I created a simple middleware that uses some functions from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;github.com/gravityblast/fresh/runner/runnerutils&lt;/code&gt;.
I made &lt;a href=&quot;https://github.com/gravityblast/fresh/blob/master/_examples/gocraft-web/main.go&quot;&gt;the same&lt;/a&gt; for &lt;a href=&quot;https://github.com/gocraft/web&quot;&gt;gocraft/web&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;a href=&quot;https://github.com/gravityblast/fresh/tree/master/_examples/gravityblast-martini&quot;&gt;gravityblast-martini&lt;/a&gt; folder there is another example using a &lt;a href=&quot;https://github.com/gravityblast/martini&quot;&gt;modified version of Martini&lt;/a&gt;
that already uses the runner lib.&lt;/p&gt;

&lt;p&gt;Check the &lt;a href=&quot;https://github.com/gravityblast/fresh&quot;&gt;repository on Github&lt;/a&gt; for more informations, and feel free to send me a pull request.&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Jan 2014 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2014/01/15/build-and-restart-your-go-web-app-with-fresh/</link>
        <guid isPermaLink="true">http://gravityblast.com/2014/01/15/build-and-restart-your-go-web-app-with-fresh/</guid>
        
        <category>go</category>
        
        <category>golang</category>
        
        <category>traffic</category>
        
        <category>martini</category>
        
        <category>gocraft-web</category>
        
        
      </item>
    
      <item>
        <title>ActiveMusicbrainz - How to use the Musicbrainz database from Ruby</title>
        <description>&lt;p&gt;If you need to use &lt;a href=&quot;https://www.ruby-lang.org&quot;&gt;Ruby&lt;/a&gt; to access the &lt;a href=&quot;http://musicbrainz.org/doc/MusicBrainz_Database&quot;&gt;Musicbrainz database&lt;/a&gt; you can use &lt;a href=&quot;https://github.com/gravityblast/active_musicbrainz&quot;&gt;ActiveMusicbrainz&lt;/a&gt;.
ActiveMusicbrainz is a library based on &lt;a href=&quot;http://edgeguides.rubyonrails.org/active_record_basics.html&quot;&gt;ActiveRecord&lt;/a&gt; that automatically creates one model for each Musicbrainz table and defines the main associations between them.&lt;/p&gt;

&lt;p&gt;If you want to use it in a rails application, add the gem dependency to the Gemfile:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gem &apos;active_musicbrainz&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You need to initialize the library after connecting to the database. In rails you can add the following line inside a file in your initializers folder:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ActiveMusicbrainz.init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The line above will initialize all the models, one for each table, even if they are not defined in the library.&lt;/p&gt;

&lt;p&gt;Now you can start playing with the musicbrainz database. You can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;by_gid&lt;/code&gt; method on all the Models that have a gid column, which defines the &lt;a href=&quot;http://wiki.musicbrainz.org/MusicBrainz_Identifier&quot;&gt;MBID&lt;/a&gt; of that resource:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;artist = ActiveMusicbrainz::Model::Artist.by_gid &apos;9a709693-b4f8-4da9-8cc1-038c911a61be&apos;
=&amp;gt; #&amp;lt;ActiveMusicbrainz::Model::Artist id: 24146, gid: &quot;9a709693-b4f8-4da9-8cc1-038c911a61be&quot;, name: &quot;Bonobo&quot;, sort_name: &quot;Bonobo&quot;, begin_date_year: 1976, begin_date_month: 3, begin_date_day: 30, end_date_year: nil, end_date_month: nil, end_date_day: nil, type: 1, area: 221, gender: 1, comment: &quot;UK electro artist Simon Green&quot;, edits_pending: 0, last_updated: &quot;2013-05-13 11:00:09&quot;, ended: false, begin_area: nil, end_area: nil&amp;gt;

artist.name
=&amp;gt; &quot;Bonobo&quot;

artist.release_groups.first.type
=&amp;gt; #&amp;lt;ActiveMusicbrainz::Model::ReleaseGroupPrimaryType id: 1, name: &quot;Album&quot;&amp;gt;

artist.release_groups.each{|r| puts r.name }
Black Sands
Dial &apos;M&apos; for Monkey
Scuba EP
Flutter
Pick Up
Terrapin
Eyesdown
...

artist.release_groups.first.releases.first.mediums
=&amp;gt; [#&amp;lt;ActiveMusicbrainz::Model::Medium id: 654199, release: 654199, position: 1, format: 1, name: nil, edits_pending: 0, last_updated: &quot;2012-01-15 13:46:18&quot;, track_count: 12&amp;gt;]

artist.release_groups.first.releases.first.mediums.first.tracks.each{|t| puts t.name}
Prelude
Kiara
Kong
Eyesdown
...

artist.release_groups.first.releases.first.mediums.first.format
=&amp;gt; #&amp;lt;ActiveMusicbrainz::Model::MediumFormat id: 1, name: &quot;CD&quot;, parent: nil, child_order: 0, year: 1982, has_discids: true&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check out the project on &lt;a href=&quot;https://github.com/gravityblast/active_musicbrainz&quot;&gt;Github&lt;/a&gt; for more info.&lt;/p&gt;
</description>
        <pubDate>Mon, 09 Dec 2013 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2013/12/09/activemusicbrainz-how-to-use-the-musicbrainz-database-from-ruby/</link>
        <guid isPermaLink="true">http://gravityblast.com/2013/12/09/activemusicbrainz-how-to-use-the-musicbrainz-database-from-ruby/</guid>
        
        <category>ruby</category>
        
        <category>activerecord</category>
        
        <category>musicbrainz</category>
        
        
      </item>
    
      <item>
        <title>How to deploy Go with Traffic on Heroku</title>
        <description>&lt;p&gt;It’s really easy to deploy a Go application based on the &lt;a href=&quot;https://github.com/gravityblast/traffic&quot;&gt;Traffic&lt;/a&gt; web framework on &lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt;.
Let’s start with a simple example.&lt;/p&gt;

&lt;p&gt;First of all, we need a simple Traffic app:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;n&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hello&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hello&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Create the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.go&lt;/code&gt; file with the following content:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;github.com/gravityblast/traffic&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;traffic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ResponseWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;traffic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WriteText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;traffic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now you should be able to run the example with:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check &lt;a href=&quot;http://localhost:7000&quot;&gt;http://localhost:7000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now we need to create a new Heroku app based on the &lt;a href=&quot;https://github.com/kr/heroku-buildpack-go&quot;&gt;Go Heroku Buildpack&lt;/a&gt;.
You can red more about that on &lt;a href=&quot;http://mmcgrana.github.io/2012/09/getting-started-with-go-on-heroku.html&quot;&gt;this tutorial&lt;/a&gt;,
but it’s very easy, we just need a couple of files and commands.&lt;/p&gt;

&lt;p&gt;Create the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.godir&lt;/code&gt; file with the app name inside:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo &apos;hello&apos; &amp;gt; .godir
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we need a file called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Procfile&lt;/code&gt; with some configuration for Traffic:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;web: TRAFFIC_PORT=$PORT TRAFFIC_ENV=production TRAFFIC_HOST=0.0.0.0 hello
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We set 3 environment variables before calling our executable.&lt;/p&gt;

&lt;h3 id=&quot;traffic_port&quot;&gt;TRAFFIC_PORT&lt;/h3&gt;

&lt;p&gt;By default Traffic runs on port 7000. You can change the port in your code using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;traffic.SetPort(3000)&lt;/code&gt; or just using the &lt;strong&gt;TRAFFIC_PORT&lt;/strong&gt; variable.&lt;/p&gt;

&lt;h3 id=&quot;traffic_env&quot;&gt;TRAFFIC_ENV&lt;/h3&gt;

&lt;p&gt;By default Traffic runs in development mode. This means that it adds some useful middleware for development like the ShowErrorsMiddleware, but you don’t want to add them in production.
To run Traffic in production mode, just set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TRAFFIC_ENV=production&lt;/code&gt;.
If you need to serve static files like css or images, you need to use the &lt;strong&gt;StaticMiddleware&lt;/strong&gt;, which is automatically loaded in development mode but not in production.&lt;/p&gt;

&lt;p&gt;To enable it in production, add the following code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if traffic.Env() == &quot;production&quot; {
  r.Use(traffic.NewStaticMiddleware(traffic.PublicPath()))
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;traffic_host&quot;&gt;TRAFFIC_HOST&lt;/h3&gt;

&lt;p&gt;By default Traffic starts on 127.0.0.1:7000, and it’s visible only from your local machine. To be able to see your application in production you need to bind it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.0.0.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we just need to initialize our git repository, create the heroku app, and deploy it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git init
git add .
git commit -am &quot;initial commit&quot;

heroku create -b https://github.com/kr/heroku-buildpack-go.git

git push heroku master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check if it works:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;heroku open
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Thu, 05 Dec 2013 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2013/12/05/how-to-deploy-go-with-traffic-on-heroku/</link>
        <guid isPermaLink="true">http://gravityblast.com/2013/12/05/how-to-deploy-go-with-traffic-on-heroku/</guid>
        
        <category>go</category>
        
        <category>golang</category>
        
        <category>traffic</category>
        
        <category>heroku</category>
        
        
      </item>
    
      <item>
        <title>musiXmatch API library for NodeJS</title>
        <description>&lt;p&gt;I’ve just published my first &lt;a title=&quot;NPM&quot; href=&quot;http://npmjs.org/&quot;&gt;NPM&lt;/a&gt; package, and it’s called &lt;a title=&quot;musiXmatch for NodeJS&quot; href=&quot;http://search.npmjs.org/#/musixmatch&quot;&gt;musixmatch&lt;/a&gt;. With this library you can easily use the &lt;a title=&quot;musiXmatch&quot; href=&quot;http://musixmatch.com/&quot;&gt;musiXmatch&lt;/a&gt; API with a few lines of javascript.
Install it with NPM:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;npm install -g musixmatch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And here an example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var util  = require(&quot;util&quot;);
var mXm   = require(&quot;musixmatch&quot;);

mXm.Config.API_KEY = &quot;YOUR_API_KEY&quot;;

var successCallback = function(modelOrCollection) {
  console.log(&quot;Success:&quot;);
  console.log(&quot;  &quot; + util.inspect(modelOrCollection));
};

var errorCallback = function(response) {
  console.log(&quot;Error callback:&quot;);
  console.log(&quot;  &quot; + util.inspect(response));
};

mXm.API.getTrack(TRACK_ID, successCallback, errorCallback);
mXm.API.getLyrics(LYRICS_ID, successCallback, errorCallback);
mXm.API.getArtist(ARTIST_ID, successCallback, errorCallback);
mXm.API.getAlbum(ALBUM_ID, successCallback, errorCallback);
mXm.API.getSubtitle(TRACK_ID, successCallback, errorCallback);
mXm.API.searchTrack({q: QUERY}, successCallback);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want you can set your musiXmatch API KEY as an environment variable, and you won’t need to set it in your code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export MUSIX_MATCH_API_KEY=&quot;YOUR_API_KEY&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can find the source code on &lt;a href=&quot;https://github.com/gravityblast/musixmatch-node&quot; title=&quot;musiXmatch node&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 12 Feb 2012 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2012/02/12/musixmatch-api-library-for-nodejs/</link>
        <guid isPermaLink="true">http://gravityblast.com/2012/02/12/musixmatch-api-library-for-nodejs/</guid>
        
        <category>javascript</category>
        
        <category>nodejs</category>
        
        
      </item>
    
      <item>
        <title>web-app-theme 0.6.1 for rails 3</title>
        <description>&lt;p&gt;The new version of &lt;a href=&quot;http://github.com/gravityblast/web-app-theme&quot;&gt;web-app-theme&lt;/a&gt; finally supports Rails 3. Check out the &lt;a href=&quot;http://github.com/gravityblast/web-app-theme&quot;&gt;repository on github&lt;/a&gt;. It also supports &lt;a href=&quot;http://haml-lang.com/&quot;&gt;Haml&lt;/a&gt; template generation using html2haml, like &lt;a href=&quot;http://github.com/plataformatec/devise&quot;&gt;devise&lt;/a&gt; does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: the version 0.6.2 fixes a bug in the Haml generation when you use form_for blocks.&lt;/p&gt;
</description>
        <pubDate>Mon, 27 Sep 2010 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2010/09/27/web-app-theme-0-6-1-for-rails-3/</link>
        <guid isPermaLink="true">http://gravityblast.com/2010/09/27/web-app-theme-0-6-1-for-rails-3/</guid>
        
        <category>Development</category>
        
        <category>Ruby</category>
        
        
      </item>
    
      <item>
        <title>Ruby library for the musiXmatch API</title>
        <description>&lt;p&gt;If you want to search for lyrics and tracks with Ruby using the &lt;a href=&quot;http://musixmatch.com&quot; title=&quot;musiXmatch&quot;&gt;musiXmatch&lt;/a&gt; API, check out my repository at &lt;a href=&quot;http://github.com/gravityblast/musix_match&quot;&gt;http://github.com/gravityblast/musix_match&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 20 Sep 2010 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2010/09/20/ruby-library-for-the-musixmatch-api/</link>
        <guid isPermaLink="true">http://gravityblast.com/2010/09/20/ruby-library-for-the-musixmatch-api/</guid>
        
        <category>Development</category>
        
        <category>Ruby</category>
        
        
      </item>
    
      <item>
        <title>Don&apos;t abuse NSLog in your iPhone game</title>
        <description>&lt;p&gt;I’m working on a simple game for iPhone based on &lt;a href=&quot;http://www.cocos2d-iphone.org/&quot; title=&quot;Cocos2d&quot;&gt;cocos2d&lt;/a&gt;. Yesterday I installed it on my old iPhone3G and it was veeeeeeeery slow. After a lot of refactoring I found a NSLog call inside my game loop. It basically logged all the collision detection of the player with all the tiles in the map. After removing that it’s even faster then before. So, if you want to log something, do it, but remember to remove all these logging calls later.&lt;/p&gt;
</description>
        <pubDate>Thu, 08 Apr 2010 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2010/04/08/dont-abuse-nslog-in-your-iphone-game/</link>
        <guid isPermaLink="true">http://gravityblast.com/2010/04/08/dont-abuse-nslog-in-your-iphone-game/</guid>
        
        <category>Cocos2d</category>
        
        <category>Development</category>
        
        <category>iPhone</category>
        
        
      </item>
    
      <item>
        <title>Using CouchDB from Air applications with CouchDB Flex</title>
        <description>&lt;p&gt;In the last weeks I played a lot with &lt;a href=&quot;http://couchdb.apache.org/&quot; title=&quot;CouchDB&quot;&gt;CouchDB&lt;/a&gt; and I love it. I always used it from ruby but yesterday I tried to use it with flex. I started a new Actionscript project called &lt;a href=&quot;http://github.com/gravityblast/couchdb-flex&quot; title=&quot;CouchDB Flex&quot;&gt;CouchDB Flex&lt;/a&gt;, you can browse the source from &lt;a href=&quot;http://github.com/gravityblast/couchdb-flex&quot; title=&quot;CouchDB Flex on Github&quot;&gt;github&lt;/a&gt;. The implementation is inspired by &lt;a href=&quot;http://github.com/jchris/couchrest&quot;&gt;couchrest&lt;/a&gt;, but it’s asynchronous because I use &lt;a href=&quot;http://livedocs.adobe.com/flex/3/langref/flash/net/URLLoader.html&quot; title=&quot;URLLoaer&quot;&gt;URLLoader&lt;/a&gt; internally. Since the flash player  doesn’t support the PUT and DELETE HTTP methods, you must create an AIR project if you want to try the library.  You can find a compiled swc &lt;a href=&quot;http://github.com/gravityblast/couchdb-flex/downloads&quot;&gt;here&lt;/a&gt;, put it in your libs folder and you are ready to go. Here a small example, but it’s still in development, and a lot of functionality are not implemented yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CouchdbFlexExample.mxml:&lt;/strong&gt; the main mxml file, it&apos;s just a window with a textarea that will display the data loaded from CouchDB.&lt;/p&gt;
&lt;pre lang=&quot;actionscript3&quot;&gt;
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;c:App xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot; xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot; xmlns:c=&quot;com.gravityblast.couchdbflexexample.*&quot;&gt;
  &lt;s:TextArea id=&quot;textarea&quot; width=&quot;100%&quot; height=&quot;100%&quot; text=&quot;{log}&quot; /&gt;			
&lt;/c:App&gt;
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;com/gravityblast/couchdbflexexample/Contact.as:&lt;/strong&gt; the model I&apos;ll save on CouchDB. By default the model has a name and an email, but I can add more properties since it&apos;s a dynamic class.&lt;/p&gt;
&lt;pre lang=&quot;actionscript3&quot;&gt;
package com.gravityblast.couchdbflexexample
{
  import com.gravityblast.couchdb.Document;

  public dynamic class Contact extends Document
  {		
    public var name:String;
    public var email:String;
		
    public function Contact()
    {
      super();
    }
  }
}
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;com/gravityblast/couchdbflexexample/App.as:&lt;/strong&gt; the main application, where I create a new Contact Document, and I load all the contacts using a view created with the Design and View classes.&lt;/p&gt;
&lt;pre lang=&quot;actionscript3&quot;&gt;
package com.gravityblast.couchdbflexexample
{
  import com.gravityblast.couchdb.CouchDb;
  import com.gravityblast.couchdb.Database;
  import com.gravityblast.couchdb.Design;
  import com.gravityblast.couchdb.View;
  import com.gravityblast.couchdb.events.CouchRestEvent;
  import com.gravityblast.couchdb.events.DocumentEvent;
  import com.gravityblast.couchdb.events.ViewEvent;
	
  import mx.events.FlexEvent;
	
  import spark.components.TextArea;
  import spark.components.WindowedApplication;
	
  public class App extends WindowedApplication
  {		
    private var couchdb:CouchDb;
    private var database:Database;
		
    [Bindable]
    public 	var log:String;
    public 	var textarea:TextArea;
		
    public function App()
    {			
      this.couchdb = new CouchDb();
      this.database = this.couchdb.database(&quot;couchdb-flex-example&quot;);
      this.log = &quot;&quot;;
      this.addEventListener(FlexEvent.CREATION_COMPLETE, this.creationCompleteHandler);
      super();
    }
		
    private function creationCompleteHandler(event:FlexEvent):void
    {			
      this.database.create(this.databaseCreateHandler);	
    }
		
    private function databaseCreateHandler(event:CouchRestEvent):void
    {
      trace(event.data);
      if (event.json.ok || event.json.error.toString() == &quot;file_exists&quot;)
      {
        var map:String = &quot;function(doc) {if (doc[&apos;couchdb-flex-type&apos;] == &apos;com.gravityblast.couchdbflexexample::Contact&apos;) emit(null, doc);}&quot;;
        var view:View = new View(&quot;all&quot;, map);
        var design:Design = new Design(&quot;contacts&quot;);
        design.addView(view);
        design.save(this.designSaveHandler);	
      }
    }
		
    private function designSaveHandler(event:DocumentEvent):void
    {
      trace(event.data);									
      if (event.json.ok || event.json.error == &quot;conflict&quot;)			
        this.createContacts();
      else
        trace(&quot;Error saving design document: &quot; + event.data)			
    }
		
    private function createContacts():void
    {
      var contact:Contact = new Contact();
      contact.name    = &quot;jack&quot;;
      contact.email   = &quot;jack@example.com&quot;;
      contact.address = &quot;Jack Street&quot;;
      contact.save(this.contactSaveHandler);			
    }
		
    private function contactSaveHandler(event:DocumentEvent):void
    {			
      trace(event.data);
      var contact:Contact = event.document as Contact;
      contact.address = &quot;Jack Street updated at &quot; + (new Date()).toString();
      contact.save(this.contactUpdateHandler);			
    }
		
    private function contactUpdateHandler(event:DocumentEvent):void
    {			
      trace(event.data);
      View.load(&quot;contacts&quot;, &quot;all&quot;, {}, this.contactsLoadHandler);
    }
		
    private function contactsLoadHandler(event:ViewEvent):void
    {					
      for each (var contact:Contact in event.documents)
      {
        for (var property:String in contact.attributes)
        {
          this.log += property + &quot;: &quot; + contact[property] + &quot;\n&quot;;	
        }
        this.log += &quot;-------------\n&quot;;
      }
    }
  }
}
&lt;/pre&gt;

&lt;p&gt;I&apos;ll write more about the library as soon as it&apos;s more stable.&lt;/p&gt;
</description>
        <pubDate>Tue, 03 Nov 2009 00:00:00 +0000</pubDate>
        <link>http://gravityblast.com/2009/11/03/using-couchdb-from-air-applications-with-couchdb-flex/</link>
        <guid isPermaLink="true">http://gravityblast.com/2009/11/03/using-couchdb-from-air-applications-with-couchdb-flex/</guid>
        
        <category>AIR</category>
        
        <category>Couchdb</category>
        
        <category>Development</category>
        
        <category>Flex</category>
        
        
      </item>
    
  </channel>
</rss>
