Darwinports does some weird shtuff. I think its highly convenient, but I don’t have time to debug the myriad of issues that crop up from multiple ruby and mysql installations. So, I wiped my Darwinports /opt folder, and started anew, with native versions of everything.

Since mysql’s header libs don’t include the proper type definitions to build the mysql gem, just add it to the mysql header, and the gem will compile just fine.

In /usr/local/mysql/include/mysql.h

Put this near the top, preferably after the redundancy-check in the preprocessor directives.


#define ulong unsigned long

Then install the gem with the dependencies like so..


gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

Happy Compiling!

* Update

The Cat is out of the bag (Leopard) and a new set of issues has cropped up. Check out this wiki for some very useful commands to install the mysql gem easily

Back to Software

January 30th, 2007

Ok, that didn’t last very long. After amassing a list of musical rants, and ideas for the musical portion of my site, I decided, the scope of it all is far too large for a development site! Anyway, I have some big-ticket software/support packages coming up, for interested parties. I’ll make info available shortly!

Infant Plugin, what the heck!

January 20th, 2007

Someone actually searched for “Infant Plugins” and arrived at my site. The only thing scarier than someone searching for Infant Plugins, is AHG Software being #2 on google for it. What the !#@$ is with that, I feel like I’ve joined some creepy society for god knows what.

Neo-weed anyone?

January 20th, 2007

Shaun Inman is the man. He’s got a cool csszengarden entry AND he developed a fantastic webstats package with Mint. I, however, have wanted a more lightweight solution that I can use for each instance where I can’t justify the price for a site (such as this one, that actually costs me money!).

I tried in vain for weeks to find Weed, I remembered that the Weed package (a Mint-copy in Rails) was lambasted for being inferior, but, I thought it was a good effort by good people, and now its barely visible on the web! I finally found the sucker, and I fixed up all the bugs (I love debugging half-working relics and gettin’ them working) so I’m using it for my own sites now.

As good as it is for a quick solution, I would have coded it vastly different, using some inline C code, and various other methods of optimization. As such, I have begun coding an alternative which is coming along nicely. If anyone wants to help me beta test, just shoot me an email and we’ll set something up. Ditto, if you can’t get the latest version of Weed working, lemme know, I’ll try and help. I may even post a tutorial on it, if its not illegal (I know as much about software legality as a streetbum). Their SVN repository is still up, but I can’t find anything about why their not runnin’ anymore. Maybe they ran into efficiency issues of running an open-beta?

Update: Before I forget, I added a PhpCompat.ip2long function in my PHP Compatibility Plugin for Rails. Just about every self-tracking php app out there uses that method, so if you’re trying to port any of those apps, try using my plugin!

Liquid templates? Why?

January 19th, 2007

I’ve had some colleagues insist that Liquid Templates for Rails are the way to go? I’ve not heard any convincing arguments, other than the opinion that its flexibility and non-verbosity is a big asset in having cleaner View code. Personally, just the fact that it REEKS of Smarty in PHP is something that I want to avoid. You are coding in Ruby, why not preserve the homogeny of your application’s code by using standard ruby for all of the operations therein?

This leads in the direction of arguing the View’s importance in the MVC pattern outlined by the framework. A role which I am definitely not qualified to answer. In school we learn so much of the benefit of Data Structures, and their usage to solve problems of intense algorithmic complexity by abstracting related relationships and using innovative ways to iterate through those relationships. Those data structures were there for specific low-level purposes and algorithmic efficiency and thus, they were established and sacred (you change it, or use it incorrectly, you’d lose your algorithmic advantage, o(n) could become o(n^2) in no time!).

MVC is a structural advantage, one that serves a more ‘human’ purpose, of reducing the entropic nightmare of maintaing complex code and the interaction with developers and the system. Is preserving it, by strictly adhering to the separation of powers within, a matter of prime importance? I believe so, and in believing that, I will concede that I’m ANAL about keeping logic/processing out of the view templates. Something like Liquid or Smarty seem like such a violation of the MVC principles. At least in Smarty’s case, I’ve seen the horror of debuging processing errors in the TEMPLATES and not the controllers.

I will keep an open mind and try a few applications with Liquid. If I can find some systematic method to keep things clean and accessible for nubes, I’ll be sure to write up a tutorial!

Update: I’ve RTFM and I think I understand the purpose of Liquid Templates a bit better. However, PHB’s are STILL requesting its use on the merits of its Buzzword compliance. Its insane, I really wanted to be a part of this Web2.0 thing, but, its not really something you can force. You need a designer that thinks out of the box, a developer who’s open to new technologies, and someone to tie it all together who understands the meaning of the world ‘elegance’. At no point, should buzzword compliance enter the fray!

Apple Annoyance

January 17th, 2007

The thing that I love most about Apple is their Innovation. Their tendency to pull a 180 just when industry analysts are touting Apple’s impending doom is their trademark. They tap new markets well before Microsoft’s not-so-well-oiled machine can. Well, I believe its time for them to ‘go with the flow’ again.

Mp3 downloads are forcing the RIAA and the whole music industry to change its tactics. Upcoming developments in Movie/mpg delivery will do the same with Hollywood. And by the same token, Apple’s move to x86 should be forcing the company to re-invent their revenue plan so that it doesn’t all rely on hardware sales. Its ridiculous, fear of losing a bit off of the bottom-line on a mere FACET of their company prevents us from installing OS X on commodity hardware? Its irritating, and maybe some of you geeks will understand my frustration at seeing “Dont_Steal_Mac_OS_X.kext” sitting in my loaded kernel drivers list. That made me want to throw my Macbook Pro through the wall. Its like having Windows tell you that YOU are a thief and you are using pirated software, even though you’re running Windows XP OEM on a Dell.

If only Linux could run Aqua on top of OpenStep or something…

Damn Cold Chicago

January 16th, 2007

It is 19 degrees (F) out here. I think I understand why so many Midwest Developers migrate West. California or Bust, (or if you live in Van Nuys, both!).

Lush Theme

January 14th, 2007

I’m trying out this Lush Theme from Marco Vlieg’s Typo Theme entry. I like all of the themes, but I really think he should have won. This theme is absolutely fantastic. Anyway, as he mentions, it only works in the trunk svn builds of the latest typo, and sure enough, it breaks on my plain-jane installation of typo 4.0. Amazingly, it only needs a few fixes. First, make sure that you are replacing the sidebar component rendering with the following.


      <%= render_sidebars %>

Also, non-edge Rails “url_for” helper needs valid (as in Routeable) parameters, so, the author’s tendency to do this…


url_for :controller=>"stylesheets",:action=>"theme",:id=>"lush.css"

doesn’t work! Just replace those tags with the intended strings, so the above example could just be replaced with ”/stylesheets/theme/lush.css”.

If you are feeling too lazy to replace all the strings manually (remember, lazy is good, its the inspiration for invention, or something like that), just do it with a sed script, or heck, do it in ruby! Try this, go to your lush theme directory, fire up IRB, and do this.

1
2
3
4
5
6
Dir.glob("**/**.rhtml").each do |entry|
    contents = File.read(entry)
    File.open(entry,"w+") do |f|
        f << contents.gsub(/url_for :controller => '([^']*)', :action => '([^']*)', :id => '([^']*)'/,"\"\\1/\\2/\\3\"")
    end
end

That’ll just recursively replace the url_for helper in all the views. There may be an outstanding..


 url_for :controller=>'',:only_path=>false

.. tag somewhere giving you headaches.That tag was a problem for my OS X Rails installation. It didn’t cause any issues on my production (FreeBSD) box, however, so you should be just fine at this point! Either way, just replace it with a sensible string, and you should be runnin’ the coolest blog theme around in no time!

Erb Output Buffering

January 14th, 2007

For those of you that want some painless output buffering in Rails (when using ERB templates), I have a plugin that may help you


./script/plugin install svn://ahgsoftware.com/erb_buffer/trunk

It handles unlimited nesting of buffers, and its fairly simple to use and extend. Lemme know how you guys like it. I see plenty of people downloading but no ones commenting! Any feedback for improving them would be greatly appreciated!

Here’s an example of single buffering

1
2
3
4
5
<% @contents = capture_buffer do  %>
Buffered Content, show me later in green!
<% end %>

<p style="color: green;"><%= @contents %></p>

And here is a nesting example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<% @contents_surface = capture_buffer do  %>
        I'm heavy on top, like an inverted pyramid!
        <% @contents_shallow = capture_buffer do %>
                Only Shallow Hal would occupy this plane of existence.
                <% @contents_deep = capture_buffer do %>
                        deeper deeper
                <% end %>
        <% end %>
<% end %>

<p>ending nested buffers</p>

<%= @contents_surface %>
<%= @contents_shallow %>
<%= @contents_deep %>

I must say, that, I do not like the mvc(h) setup in Rails very much. For me, the ORM is nearly a work of art, and Rails itself is certainly a very well thought out glue for the components. I think it suffers from being too small for HUGE enterprise uses, and too large for simple 1-10 file scripts that could easily handle some simple webtask for you. I’m starting to discover that a microframework like Camping might suit 40% of my projects much better than a fullblow Rails installation, and use of captured buffers, akin to PHP’s ob_* methods, would make much more sense. I’ll let ya know when I get a production site up that breaks the Rails mold!

I really dig SWFObject in Javascript for making nice lightweight flash objects. What I really need, much more often though, is a way to present any Flash, Movie, Game, Song, or Thing easily in a view, and for it to be just like any other ActionView Helper.

So here is what I use, probably more often than any other plugin (except acts_as_authenticated)


./script/plugin install svn://ahgsoftware.com/simple_object/trunk

It’ll take whatever arbitrary parameters you give it, however, I’m lazy as hell and I just call it with no parameters, and let the code handle inferring decent defaults (although for video/image/swf you’ll want at least the width/height). Here’s how I use it.

1
2
3
4
5
6
7
8
9
simple_object '/swfs/game.swf'

simple_object '/songs/test.mp3'

simple_object '/swfs/mp3player.swf',:url=>"/mp3s/tool.mp3"

simple_object 'test.mov',:width=>"640",:height=>"480"

# and so on..

I’ll be adding support for more filetypes shortly. Enjoy!

I must have it…

This thing rocks. I can’t wait to get my hands on the developer kit. Can you imagine having a network of sites, and also XML-RPC widgets running on your phone to interact with all of your projects! Steve Jobs better make the dev-kit opensource! That truly would revolutionize the cellphone industry.

When converting legacy frameworks over to Rails, I often desire to get things working with Migrations. More often than not, Rake craps out on me, when the tablenames are reserved keywords. I usually just change tablenames, to avoid the hassle, but, in keeping with my New Years Resolution of “If I have an annoying problem, fix it, don’t walk away”, here’s a quick homebrew solution for “rake db_schema_dump” that’ll ensure that you can mash your legacy db with its weird-ass tablenames into something useable..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter < AbstractAdapter
      def indexes(table_name, name = nil)#:nodoc:
        indexes = []
        current_index = nil
        execute("SHOW KEYS FROM #{quote_column_name table_name}", name).each do |row|
          if current_index != row[2]
            next if row[2] == "PRIMARY" # skip the primary key
            current_index = row[2]
            indexes << IndexDefinition.new(row[0], row[2], row[1] == "0", [])
          end

          indexes.last.columns << row[4]
        end
        indexes
      end

      def columns(table_name, name = nil)#:nodoc:
        sql = "SHOW FIELDS FROM #{quote_column_name table_name}"
        columns = []
        execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") }
        columns
      end
    end
  end
end

I wish I knew of a leaner way to do this, but, short of having some kind of observer, or some cool trick that takes advantage of Ruby polymorphism, to which I am not privy, this will have to do. Maybe the ActiveRecord guys will escape tablenames in the next release, there are plenty of other people with the same issue!

Rotate Log File in Ruby

January 7th, 2007

Sheer laziness has had me scouring the net for a snippet to rotate logs in Ruby (not Rails, everyone already knows about the ole’ config.logger setting). Since I haven’t found anything as of yet, I’ll share my little snippet (and cry about how I spent an hour searching for something that I just wrote in about 4 minutes).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class File
  # Copies excludes the original file
  def self.rotate(filename,copies = 10)
    require 'fileutils'
    raise FileNotFound if !File.exist?(filename)
    return false if copies.to_i < 1
    
    File.unlink "#{filename}.#{copies.to_i - 1}" if File.exist?("#{filename}.#{copies.to_i - 1}")
    (copies.to_i - 2).downto(0) do |n| 
      next if !File.exist?("#{filename}.#{n}")
      File.rename("#{filename}.#{n}","#{filename}.#{n+1}") 
    end
    File.rename filename, "#{filename}.0"
    FileUtils.touch filename
  end
end

Lets say, you want to rotate lighttpd logs for your box and don’t want BSDs log rotater gettin’ its grimy hands on your hard earned traffic logs (don’t ask me anyone would feel that way). Just do this this..

1
2
3
4
# Include aforementioned code
lighttpd_log = "/var/log/lighttpd/lighttpd.access.log
backup_copies = 10
File.rotate lighttpd_log, backup_copies

Simple enough! Moral of the story? If you can’t easily find a snippet, just roll your sleeves, roll a !@#$% and roll your own solution! Thats how we roll!

She's a brickhouse!

January 4th, 2007

Or maybe she’s floor-to-ceiling windowed cot! Or a cardboard box on Michigan Avenue! Coding out of my home here in Suburbia Illinois, I’m constantly reminded of the bland architectural styles of the Midwest. Apart from the beauty of the Plano Mies/Farnsworth House ,

what do we have to be proud of out here? I’m surrounded by McMansions, and it makes me green with envy that all of my associates out in LA are enjoying their nice modern homes. Homes that don’t sacrifice their integrity by succumbing to the rampant ubiquity of prepackaged wannabe Victorian stylings.

My Resolution for 2007, among others, is to get a house that respects the environment, that avoids the ‘mine-is-bigger-than-yours’ infantile mindset that seems to govern the suburban Chicago housing market. A home that will look to the future, and that will look good, and that will have enough space in the basement so that I can build my 6 30” Cinema Display “Swordfish” setup. Evil clowns will rejoice at the abomination that will be my office. A testament to techno-Bourgeoisie excess.

Anyway, what do you guys think? Should I get an LVL with a basement from Rocio Romero (beautiful homes, really, check em out..) ?

One of those Living Homes from Dwell Magazine over in LA, would be awesome, except, imagine spending a cold Illinois winter in that glass monstrosity. One word… SHRIVEL.

Or should I just buy something already made and tempered by the tyranny of time. Maybe I could listen to Andrew Lloyd Weber in my Frank Lloyd Wright. It’d be better than listening to Rent in my lakefront Rental (No offense Mr. Larson, RIP).

Whatever it is, I guarantee, it’ll be comfortable. It’ll have a PS4,XBox720, AND a Wii2 all ready to go for ‘work-breaks’. It’ll have a guitar in every room (Yes, I play a little bit ;) ). And, I even have screaming kids to round out the package!

Just a quick addendum to my previous Post. Quick and Dirty CSS-classes to inline-styles for newsletter/mailouts could be done with that obnoxious php code that I posted (I know, you obfuscated C-type of coders probably could do a nice perl-oneliner to do the replacement AND do you laundry), but, look how much nicer the same code looks in ruby..

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env ruby

html = File.read 'newsletter.html'
css = File.read 'newsletter_stylesheet.css'

def merge_html_and_stylesheet(html,css)
  css.scan(/\.(\w+)\s+\{([^\}]*)\}/m).each do |rule|
    html.gsub!(/class="#{rule[0]}"/,"style=\"#{rule[1]}\"")
  end
  html
end

puts merge_html_and_stylesheet(html,css)

Aaaaaaah… Coding bliss, Ruby is just the greatest language. Rather pythonish, but, without those stupid lookin’ colon’s at the end of control structures. There should only be one colon at the end, and you Proctologists know EXACTLY what i’m talkin’ ‘bout!

One thing that ALWAYS happens to me is that I’ll get an urgent task to take an html page and send it as an email to a list of users. After about the billionth time in the last few months that I’ve had to do this, I thought I’d share a helpful snippet that makes my day…

Since, GMail, Hotmail, and Yahoo all strip ‘class=”classname”’ attributes from html tags, you can’t use your normal css tricks, so I run a little inline search-replace that extracts attributes from SIMPLE css files, and forces them to be inline eg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# CSS File
.classname {
   border:1px solid green;
   background-image: url(images/ugly.jpg);
}

div.titles {
   font-size: 2em;
   color: #020202;
}

# HTML file
<div class="titles">
  <div class="classname"> 
  </div> 
</div>

# Turns into...
<div style="border:1px solid green;background-image: url(images/ugly.jpg);">
  <div style="font-size: 2em;color: #020202;"> 
  </div>   
</div>

It doesn’t fix everything, but, its saved my butt on too many occasions to not share :)
Here is the function. Feel free to make it more robust, but, remember, move your css inline if you want the best results and check it before you send it!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    $html = file_get_contents("sample.html");
    $css = file_get_contents("sample.css");
    mail("test@domain.com","Testing html inline",merge_html_and_stylesheet($html,$css),"Content-type: text/html\r\n");

    function merge_html_and_stylesheet($html,$css) {
        $contents = $html;
        // Extract some classes (we are ignoring ids, or complicated rules for now
        preg_match_all("/\.([a-zA-Z0-9]+)\s+{([^}]*)}/m", $css, $matches);
        $styles = array();
        for($i = 0; $i < count($matches[0]); $i++) {
            $styles[$matches[1][$i]] = $matches[2][$i];
        }
        // Replace classes with inline styles
        preg_match_all("/class=\"([a-zA-Z0-9]+)\"/", $contents, $matches);
        $cache = array();
        for($i = 0; $i < count($matches[0]); $i++) {
             $contents = str_replace("class=\"" . $matches[1][$i] . "\"","style=\"" .
            $styles[$matches[1][$i]] . "\"", $contents);
        }
        return $contents;
    }

GnuPG Ruby on Rails Plugin

January 1st, 2007

I have another alpha-level plugin for you folks. This one has also saved me arse on many an occasion. Keep in mind, encryption/decryption setups on servers vary like the color of leaves in autumn. This particular plugin works on the paradigm of having a web-accessible public key that encrypts user data, and a temporarily available secret key that is used for decryption. Its entirely up to you to ensure that things are kept secure, but, as a result, the plugin is tiny!


./script/plugin install svn://ahgsoftware.com/gnupg/trunk

Here’s a quick example, assuming you have a pub key—imported

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# We're using the same workdir for pub and sec, they could differ!
workdir = File.join(RAILS_ROOT,"tmp","gnupg")
passphrase = "uglydonkeys"

# This is a darwin-ports on Mac OS X version of gpg
gnupg = GnuPG.new :binary=>"/opt/local/bin/gpg",
   :workdir=>workdir,
   :homedir_pub=>workdir,
   :homedir_sec=>workdir,
   :recipient=>"your uid"

plain_message = "no more mustachoed tyrants, muhwahwahwa, buhwahwahwa"
encrypted_message = gnupg.encrypt(plain_message)

# Load ascii sec key, from wherever you might have it
gnupg.load_key File.read("sec_key.asc")
decrypted_message = gnupg.decrypt(encrypted_message, passphrase)
gnupg.drop_key

puts plain_message
puts encrypted_message
puts decrypted_message

 

Michael Cerna Chicago-based Rails Developer and Avid Musician. More ...

Search

Categories

  • Home (15)
  • Rails Plugins (5)
  • Pages (9)
  • Archives

    Tags

    BlogRoll