<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>The Book of Ryan &#187; Web Tools</title>
	<atom:link href="http://ryancannon.com/category/web-designprogramming/web-tools/feed" rel="self" type="application/rss+xml" />
	<link>http://ryancannon.com</link>
	<description>Wordslinger, dissident, webwright</description>
	<lastBuildDate>Mon, 06 Jul 2009 17:19:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- podcast_generator="podPress/8.8" -->
		<copyright>&#xA9; </copyright>
		<managingEditor>ryan@ryancannon.com ()</managingEditor>
		<webMaster>ryan@ryancannon.com()</webMaster>
		<category></category>
		<ttl>1440</ttl>
		<itunes:keywords></itunes:keywords>
		<itunes:subtitle></itunes:subtitle>
		<itunes:summary>Wordslinger, dissident, webwright</itunes:summary>
		<itunes:author></itunes:author>
		<itunes:category text="Society &amp; Culture"/>
		<itunes:owner>
			<itunes:name></itunes:name>
			<itunes:email>ryan@ryancannon.com</itunes:email>
		</itunes:owner>
		<itunes:block>No</itunes:block>
		<itunes:explicit>no</itunes:explicit>
		<itunes:image href="http://ryancannon.com/wp-content/attic/images/album_art-144x144.png" />
		<image>
			<url>http://ryancannon.com/wp-content/attic/images/album_art-144x144.png</url>
			<title>The Book of Ryan</title>
			<link>http://ryancannon.com</link>
			<width>144</width>
			<height>144</height>
		</image>
		<item>
		<title>Setting up A Rails Application for EVE Online</title>
		<link>http://ryancannon.com/2008/02/06/setting-up-a-rails-application-for-eve-online</link>
		<comments>http://ryancannon.com/2008/02/06/setting-up-a-rails-application-for-eve-online#comments</comments>
		<pubDate>Wed, 06 Feb 2008 09:54:39 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Design/Programming]]></category>
		<category><![CDATA[Web Tools]]></category>

		<guid isPermaLink="false">http://ryancannon.com/2008/02/06/setting-up-a-rails-application-for-eve-online</guid>
		<description><![CDATA[As I mentioned before, I&#8217;ve be having a lot of fun with EVE Online. The attraction, however, hasn&#8217;t been just to the ability to fly around in a ship and blast pirates (as if that weren&#8217;t enough!). EVE has a pretty excellent API, an browser that provides in-game information, and even dumps of art and [...]]]></description>
			<content:encoded><![CDATA[<p>As I <a href="http://ryancannon.com/2008/01/13/new-year-new-addiction" title="The Book of Ryan  » New Year, New Addiction">mentioned before</a>, I&#8217;ve be having a lot of fun with <a href="http://eve-online.com/" title="EVE Online - a massive multiplayer online roleplaying space game">EVE Online</a>. The attraction, however, hasn&#8217;t been just to the ability to fly around in a ship and blast pirates (as if that weren&#8217;t enough!). EVE has a pretty excellent <a href="http://myeve.eve-online.com/api/doc/" title="EVE API Documentation">API</a>, an browser that provides <a href="http://bughunters.addix.net/igbtest/IGB-commands.html" title="EVE Ingame (sic) Webbrowser (sic)">in-game information</a>, and even <a href="http://myeve.eve-online.com/ingameboard.asp?a=topic&amp;threadID=650828" title="Trinity 1.0 Static Data Export">dumps of art and data</a> for developers to <a id="ref-license" href="http://ryancannon.com/2008/02/06/setting-up-a-rails-application-for-eve-online#note-license">use</a>.</p>

<p>I&#8217;ve already got a few ideas on fun things to do with all of this data. The trick is trying to make opinionated Rails play nice with the browser, the API and the Data. To that end, here are the strategies I&#8217;m invoking. Comments are, of course, welcome.</p>

<p><span id="more-170"></span></p>

<h3>Dealing with Data</h3>

<p>I can&#8217;t even begin to wrap my brain around the cool things you can do with EVE data. A number of desktop applications exist for character tracking and skill planning, but that&#8217;s only a very shallow bit of what&#8217;s possible. Getting the data into manageable form, however, is a bit tricky.</p>

<p>I wanted to keep my EVE data separate from my game data. Presumably EVE&#8217;s data will change over time. Ideally a new dump will come out and I can just swap it with my current one&#8211;no fuss, no muss. I downloaded the <a href="http://dl.eve-files.com/media/0712/trinity_1.0_sqlite3.db.zip" title="A ZIP archive of the Trinity DB file">Trinity 1.0 SQLite3 dump</a>. And dropped it into <code>db/</code> of my Rails application. Then I had to make sure to point all EVE data to the correct database.</p>

<pre><code>config/datbase.yml:

eve_development:
  adapter: sqlite3
  database: db/trinity_1.0_sqlite3.db
  timeout: 5000
eve_test:
  adapter: sqlite3
  database: db/trinity_1.0_sqlite3.db
  timeout: 5000
eve_production
  adapter: mysql
  database: *******
  username: ********
  password: ********
  host: *******
</code></pre>

<p>and</p>

<pre><code>app/models/eve_data.rb:

class EveData &lt; ActiveRecord::Base
  establish_connection "eve_#{RAILS_ENV}"
end
</code></pre>

<p>Now any model that subclasses EveData will point to the correct database and key:</p>

<pre><code>app/models/race.rb:

class Race &lt; EveData
  set_table_name :chrRaces
  set_primary_key :raceID
  has_many :careers, :foreign_key =&gt; :raceID
end
</code></pre>

<p>The tedious part of this is setting up all of the associations, as EVE data does not conform to rails column naming conventions (although it&#8217;s not unimaginable that one could fix this with an elegant script).</p>

<p>One last note: if you generate any sub-classes of EveData using the built-in generators, be sure to remove <code>test/fixtures/&lt;subclass&gt;.yml</code> as it will cause you tests to die horrible deaths.</p>

<h3>API Wrangling</h3>

<p>Rails has a lot of built-in API magic, all of which is absolutely worthless with EVE. Consuming the EVE API requires a lot of anonymous XML parsing. Boooooring! Luckily, <a href="http://www.crudvision.com/" title="CrudVision">Lisa Seelye</a> has an excellent <a href="http://www.crudvision.com/reve-ruby-eve-online-api-library/" title="REVE - Ruby Eve Online API Library">wrapper module for the EVE API</a>. So long as you&#8217;re okay with her clear-as-mud license, Lisa&#8217;s work will be a great benefit.</p>

<h3>Managing the EVE Browser</h3>

<p><strong>Update:</strong> I&#8217;ve written up a slightly better way to <a href="http://ryancannon.com/2008/02/14/eve-on-rails-creating-an-eve-in-game-optimised-version-of-your-rails-site" title="EVE on Rails - Creating an EVE in-game-optimised version of your Rails site">target the EVE Browser in Rails 2.0</a>.</p>

<p>The EVE Online browser stinks. I got only halfway through the HTML 4.01 test suite before quitting out of frustration. I&#8217;m pretty sure it can&#8217;t even render GIF images. I&#8217;d love to see them bundle WebKit instead. One thing the browser does, however, is provide custom HTTP headers (without the required X- in front, of course) for in-game EVE data. Custom headers are available to the controller in the <code>request.env</code> collection. I made them available to all controllers and views with the following:</p>

<pre><code>app/controllers/application.rb:

class ApplicationController &lt; ActionController::Base
  ...
  # Provides access to views
  helper_method :eve?
  helper_method :trusted?
  helper_method :eve_data

  private
    def eve?
      !! request.env['HTTP_EVE.TRUSTED']
    end
    def trusted?
      request.env['HTTP_EVE.TRUSTED'] == "yes"
    end
    def eve_data
      if trusted?
        {
          "name" =&gt; request.env['HTTP_EVE.CHARNAME'],
          "id" =&gt;  request.env['HTTP_EVE.CHARID'],
          "alliance" =&gt; request.env['HTTP_EVE.ALLIANCENAME'],
          "region" =&gt; request.env['HTTP_EVE.REGIONNAME'],
          "constellation" =&gt; request.env['HTTP_EVE.CONSTELLATIONNAME'],
          "solar system" =&gt; request.env['HTTP_EVE.SOLARSYSTEMNAME'],
          "station" =&gt; request.env['HTTP_EVE.STATIONNAME'],
          "corporation" =&gt; request.env['HTTP_EVE.CORPNAME'],
          "role" =&gt; request.env['HTTP_EVE.CORPROLE']
        }
      end
    end
end
</code></pre>

<p>The <code>eve?</code> and <code>trusted?</code> methods return booleans and <code>eve_data</code> a hash of the character&#8217;s current location in-game. They allow me to write helpers such as</p>

<pre><code>app/helpers/application_helper.rb:

def character_image_tag(id, size, options = nil)
  if eve?
    o = { :src =&gt; "#{src}:#{id}", :size =&gt; "#{size}" }
    o.merge!(options) if options.is_a(Hash)
    tag(:img, o)
  else
    o = { :width =&gt; "#{size}", :height =&gt; "#{size}" }
    o.merge!(options) if options.is_a(Hash)
    image_tag("http://img.eve.is/serv.asp?s=#{size}&amp;c=#{id}", o)
  end
end
</code></pre>

<p>Guessing by the speed of the browser, using in-game resources instead of external will save the user a lot of time.</p>

<p>As players fly around EVE, the application has the ability to detect a location change and refresh the page, updating the location information. Applications could work in EVE from only one URL, even without JavaScript. In order to do so, however, the application must do some header-gymnastics as well. My take on this is something akin to:</p>

<pre><code>app/controllers/foo_controller.rb:

class FooController &lt; ApplicationController
  def index
    # Tell the client your content will change
    # Not necessary, but correct and future-proof
    response.headers["Vary"] = "eve.trustme"
    if ! eve?
      # Do something to the regular browser
      render :action =&gt; "external"
    elsif ! trusted?
      trust_me
      render :action =&gt; "trust_me"
    else
      lookup
      render :action =&gt; "lookup"
    end
  end

  def external
    ...
  end

  def trust_me
    # Send the trust header
    response.headers["eve.trustme"] = "http://#{request.env['HTTP_HOST']}/::Trust me."
    ...
  end

  def play
    # Send the auto-refresh header
    response.headers["refresh"] = "sessionchange;URL=#{url_for(:controller =&gt; 'foo')}"
    ...
  end

end
</code></pre>

<p>Each action will then have its own view file and its own logic, but the same URL. Be careful where you send the auto-refresh header: create, update and delete actions should not get them. Note too that the <code>trust_me</code> action <em>should</em> end with <code>render =&gt; :nothing</code> or similar. <em>This does not work.</em> The EVE browser requires a text/html file to trigger the trust prompt.</p>

<p>And that&#8217;s it! You&#8217;re on your way to a Rails-powered EVE application. Please send me any questions, critiques or issues. I&#8217;ll post more often with other quirks I pick up.</p>

<p>UPDATE: Modified the database set-up to use my database.yml for EVE data and connect EVE data to my environments. Also moved establish_connection into the model where it should be. I also added a note on fixtures that took me a silly amount of time to work around.</p>

<h3>Notes</h3>

<ol>
<li><span id="note-license"></span> I haven&#8217;t been able to find a license for this data. Although I&#8217;m guessing it&#8217;s Creative Commons Attribution-DontDoAnythingStupid. <a class="return" href="#ref-license">↩</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://ryancannon.com/2008/02/06/setting-up-a-rails-application-for-eve-online/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Exciting Changes</title>
		<link>http://ryancannon.com/2004/08/09/7</link>
		<comments>http://ryancannon.com/2004/08/09/7#comments</comments>
		<pubDate>Mon, 09 Aug 2004 14:19:42 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Site Announcements]]></category>
		<category><![CDATA[Web Design/Programming]]></category>
		<category><![CDATA[Web Tools]]></category>

		<guid isPermaLink="false">http://www.ryancannon.com/blog/?p=7</guid>
		<description><![CDATA[RyanCannon.com is seeing a rebirth. The newer, more relevant, content-based and (hopefully) exciting site will contain much of the same content (journal, guestbook, road trip gallery, writing and forum), but will also contain more web design-based styles and techniques ( see the CanoeScripts and CSS+JS sections ).]]></description>
			<content:encoded><![CDATA[<p><a href="http://ryancannon.com">RyanCannon.com </a> is seeing a rebirth. The newer, more relevant, content-based and (hopefully) exciting site will contain much of the same content (journal, guestbook, road trip gallery, writing and forum), but will also contain more web design-based styles and techniques ( see the <a href="http://ryancannon.com/design/canoescripts/">CanoeScripts</a> and <a href="http://ryancannon.com/design/cssjs/">CSS+JS</a> sections ).</p>

<p>Similarly, the emerging <a href="http://www.alma.edu/">Alma College</a> site is exploding and close to finish. I&#8217;ve enjoyed working on and improving the site&#8212;I&#8217;ve learned more from this project than my self-guided study over the past few years. It makes me think more excitedly about a future in the industry.</p>
]]></content:encoded>
			<wfw:commentRss>http://ryancannon.com/2004/08/09/7/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
