Rocky Migration

Posted by BadReligion Sun, 06 Sep 2009 23:02:00 GMT

So the move to Typo has not gone as smooth as I'd hoped. Not to any fault of the Typo software, I feel that the issues are mostly related to typical migration from a custom built application to a prebuilt solution. Furthermore I am not turning back by any means. I know that once I get some of the details ironed out the site will get more attention and I will be much happier with it.

I need to tweak my Capistrano deployment scripts to be Typo friendly. Some confusion seems to exist when Capistrano tries to restart Typo, I have concluded that when Typo tries to stop the current running daemon it cannot find the pid.txt because it exists in the previous release which has already been unlinked. Some simple Capistrano magic will fix that.

I am also having some issues with themes. They worked fine at first but now it seems that only the default Typo theme actually installs its images and stylesheets into public. Each theme when active installs its custom images and stylesheets into public/images/theme and public/stylesheets/theme. The proper URL's are not generated either.

Lastly I have only migrated in the old blogs, I have migrated categories but none are linked up yet. I will probably migrate the comments, but since so few exist I have prioritized getting the site functioning the way I want it.

Posted in , , ,  | Tags , , , , ,  | no comments

Considering Moving To Typo

Posted by BadReligion Thu, 03 Sep 2009 10:00:00 GMT

I am considering moving the site to Typo to replace the blog and using Flickr to manage the photo album. I am not sure what I will do about the Utilities. I need to see if I can easily extend Typo or not.

The main reason for this is simply that I end up spending more time managing code and adding new features than I do managing the content of the site. I have yet to dive into Typo and see what capabilities are there. Hopefully if I decide to make this migration, the change will cause me to upload more photos, write more blogs about stuff nobody cares about, and just improve the content of the site in general.

Sean

Posted in , , ,  | no comments

Love Models

Posted by BadReligion Tue, 14 Jul 2009 12:11:00 GMT

I wanted a DRY way to set the published_at attribute of a Blog. Remembering the advice of my peers to keep a fat model I decided to stuff the logic there. This could be used for any similar attribute. First decide on a method name that we will call on our instance variable, I decided to use "publish?". So for instance I can call "@blog.publish?", now I know I will need to know whether or not to publish the blog and I am just directly passing in the value of my published check box from params. Be sure to sanitize anything an end user can control, in this case only I use this behind an admin.

Now we need to define this method in the model, in my case "blog.rb". Its easier to show what this method looks like, then explain it.

Class Blog << ActiveRecord::Base
  ...
  def publish?(bool)
    bool ? self.published_at = Time.now : self.published_at = nil
  end
end

We define this method just like any other, we expect a boolean as an input. First we simply set the published_at to Time.now if 1 is passed in (check box is checked) otherwise set published_at to nil, effectively un-publishing the blog. However, we do not want to update the published_at with a new timestamp if the article has already been published. Although this could be dependent on the expected behavior of the application, I personally don't think it makes sense. Reason is I sort articles by published_at, I do not want them popping back up if I go back and edit them. That is what I have an updated_at attribute for.

I often found myself wondering why bother with all this...just slap another conditional in the controller, copy paste, no big deal. However as you add more and more code, the controller quickly gets out of hand and turns into complete anarchy. Refactoring your code and continually enforcing the "fat model" theory will make your controllers (and code) much easier to manage later on. Take it from someone who as learned the hard way!

Thanks for reading... Sean

Posted in  | no comments

Writing Cron Jobs With Rails Part 1

Posted by BadReligion Fri, 26 Jun 2009 08:42:00 GMT

I am working on a personal use Rails application that I use to create reminders using Cron...

There are a couple gems that are useful for dealing with Cron using Ruby. The first is rbcrontab which allows you to create crontab entries using Ruby. The other is trak3r-crontabr which actually maintains a crontab using Ruby. The latter of the two might be easier to use for those who do not understand Cron syntax but know Ruby well. I am leaning toward rbcrontab right now simply because I feel it may fit my needs better than trak3r-crontabr.

I'm not sure that I really need a full blown web interface or not. It would be nice but I think what I really need is just a mailer with templates. I don't know, once I figure out the details I will make a part 2.

Sean

Posted in , ,  | no comments

Calculating Attachment Fu Disk Usage In Rails

Posted by BadReligion Mon, 02 Feb 2009 01:33:00 GMT

So I’ll keep this one short and to the point. I wanted to see in the admin of my site how much disk space each photo album was taking up, and also a grand total of all photo albums. As noted in the title I am using Attachment Fu in Rails. The latter of the two is very easy, I could just use a system call to du -chs and be done with it, or I could do some fun programming! Here is what I did…

To find the disk usage of a particular photo album is not completely simple. I need to consider each of three thumbnail sizes for each image as well as the original image itself. I might as well take advantage of the attachment_fu helpers in some sort of nested looping.

Ok, I’m beginning to rant so here’s the damn code:

Calculating size of each photo album.



  def photo_album_size(album)

    album_size = 0

    album.pictures.each do |p|

      album_size += File.size(DOCUMENT_ROOT + p.public_filename)

      p.thumbnails.each do |t|

        album_size += File.size(DOCUMENT_ROOT + t.public_filename)

      end

    end

    return album_size

  end

 

Calculating grand total of all photo albums.



  def total_photo_albums_size()

    albums_size = 0

    albums = PhotoAlbum.find(:all)

    albums.each do |a|

      a.pictures.each do |p|

        albums_size += File.size(DOCUMENT_ROOT + p.public_filename)

        p.thumbnails.each do |t|

          albums_size += File.size(DOCUMENT_ROOT + t.public_filename)

        end

      end

    end

    return albums_size

  end

 

So thats it. I threw these in my photo albums helper and they work pretty well. By the way DOCUMENT_ROOT will have to be defined or you will have to substitute for it in some other way.

Sean

Posted in , ,  | no comments

Hacking Lightbox

Posted by BadReligion Wed, 21 Jan 2009 11:06:00 GMT

In case it wasn’t obvious I use Lightbox to make my photo album a little flashy. However, I never really read the Lightbox documentation, I simply used the Rails plugin view helper. I have for a while been wondering how to pass in an array of pictures and have the ability to click through them in the light box. When I looked at the HTML generated by the view helper I realized it wasn’t doing much. See the Lightbox homepage for more info. Then after seeing how easy it is to tell Lightbox about having more than one picture I dove in. Bear in mind I have always steered clear of JavaScript. I just never liked it. Aw, forget it I’ll cut right to the point! I didn’t like the default layout of the light box. A hover property splits the light box 50/50 and uses that to display the previous and next buttons. I just wanted them to always be displayed at the bottom with the close button and other data.

I am not in the mood to describe everything I did with the code so here is a diff of the lightbox.js. I won’t post my hackish style sheet modifications…I won’t even go there….I hate writing CSS.

For some unexplainable reason I deleted some code while only commenting other code. Whatever, maybe someone will find this useful:

==
65,68c65
< //var fileBottomNavCloseImage = "/images/closelabel.gif";
< var fileBottomNavCloseImage = "/images/custom-close-label.png"
< var fileBottomNavNextImage = "/images/custom-nextlabel.png"
< var fileBottomNavPrevImage = "/images/custom-prevlabel.png"
---
> var fileBottomNavCloseImage = "/images/closelabel.gif";
73c70
< var resizeSpeed = 8;          // controls the speed of the image resizing animations (1=slowest and 10=fastest)
---
> var resizeSpeed = 7;          // controls the speed of the image resizing animations (1=slowest and 10=fastest)
296a294,303
>               var objPrevLink = document.createElement("a");
>               objPrevLink.setAttribute('id','prevLink');
>               objPrevLink.setAttribute('href','#');
>               objHoverNav.appendChild(objPrevLink);
>
>               var objNextLink = document.createElement("a");
>               objNextLink.setAttribute('id','nextLink');
>               objNextLink.setAttribute('href','#');
>               objHoverNav.appendChild(objNextLink);
>
335,352d341
<               var objPrevLink = document.createElement("a");
<               objPrevLink.setAttribute('id','prevLink');
<               objPrevLink.setAttribute('href','#');
<               objBottomNav.appendChild(objPrevLink);
<
<                 var objPrevLinkImage = document.createElement("img");
<                 objPrevLinkImage.setAttribute('src', fileBottomNavPrevImage);
<                 objPrevLink.appendChild(objPrevLinkImage);
<
<               var objNextLink = document.createElement("a");
<               objNextLink.setAttribute('id','nextLink');
<               objNextLink.setAttribute('href','#');
<               objBottomNav.appendChild(objNextLink);
<
<                 var objNextLinkImage = document.createElement("img");
<                 objNextLinkImage.setAttribute('src', fileBottomNavNextImage);
<                 objNextLink.appendChild(objNextLinkImage);
<
425,426c414,415
<               //Element.hide('prevLink');
<               //Element.hide('nextLink');
---
>               Element.hide('prevLink');
>               Element.hide('nextLink');
472,473c461,462
<               //Element.setHeight('prevLink', imgHeight);
<               //Element.setHeight('nextLink', imgHeight);
---
>               Element.setHeight('prevLink', imgHeight);
>               Element.setHeight('nextLink', imgHeight);
==

I am dirty, tired and don’t feel like writing about this anymore.

Sean

Posted in ,  | no comments

Website moved

Posted by BadReligion Sun, 07 Dec 2008 02:12:00 GMT

Well as far as the website goes, the move has been made. It wasn’t a total success but I’m just glad I now have full control to configure everything the way I want it. I unfortunately answered wrong when I told the BlueHost representative that I didn’t need any files off the server. I had a backup of my files but not the database. Which really sucks because two days earlier I had written a database backup script and put it in cron. I did take the content out of Google’s page caches and recreated some of the blogs from it. Anyway things will be much better now and I can’t wait to test my capabilities. It may not look different but the site will have a much faster response time now. FastCGI was just bogging it down especially on shared hosting. I will also be able to set up better caching. I have yet to setup a mail server but I have other things to focus on at the moment, perhaps I will get that done either later today or more likely tomorrow.

I am using “Capistrano” to deploy now so I have been heavily customizing its tasks as well. You can do some interesting things with “Capistrano” many of which are even beyond my skill and creativity. For instance the default deploy:restart task wasn’t working with my application. I could have investigated the issue but instead I figured why not just write a new one since its a simple command to restart my Mongrel clusters. I took this code snippet I found here and modified it to just replace the default tasks as shown below.

namespace :deploy do
  [ :start, :restart, :stop ].each do |t|
    desc "#{t.to_s.capitalize} mongrel using mongrel_cluster_ctl"
    task t, :roles => :app do
      sudo "mongrel_cluster_ctl #{t.to_s} -c #{mongrel_conf}"
    end
  end
end

Since we are using the same namespace:task scheme these will get called in place of the default tasks. If you want to keep the defaults in place just change the namespace to suit your needs and add in the proper hooks.

I’m out of here for now

Sean

Posted in , , ,  | no comments

Methods Madness

Posted by BadReligion Sat, 06 Dec 2008 12:19:00 GMT

Ever call a method on a class in Rails or even just Ruby and got this:

NoMethodError: undefined method `never’ for Time:Class

Now you swear on everyone that means anything to you, that the method you are using exists. Sure it does! No, really we believe you, but lets ask Ruby since, after all she should know best right! Now before I continue I wouldn’t know about this if some time ago my co-worker, Crazy Chicken Fingers, would not have told me about the methods method. So lets see what happens:

irb(main):003:0> Time.methods
=> ["inspect", "pretty_print", "private_class_method", "const_missing", "clone", "method", "public_methods", "public_instance_methods", "instance_variable_defined?", "method_defined?", "superclass", "equal?", "freeze", "mktime", "included_modules", "const_get", "pretty_print_instance_variables", "methods", "respond_to?", "_load", "module_eval", "class_variables", "now", "dup", "protected_instance_methods", "instance_variables", "public_method_defined?", "__id__", "pretty_inspect", "eql?", "object_id", "const_set", "id", "at", "singleton_methods", "send", "class_eval", "taint", "utc", "frozen?", "instance_variable_get", "include?", "private_instance_methods", "__send__", "instance_of?", "private_method_defined?", "to_a", "name", "autoload", "type", "new", "<", "protected_methods", "instance_eval", "<=>", "display", "==", ">", "===", "instance_method", "gm", "instance_variable_set", "kind_of?", "extend", "protected_method_defined?", "const_defined?", ">=", "ancestors", "to_s", "<=", "public_class_method", "pretty_print_cycle", "allocate", "hash", "pretty_print_inspect", "class", "instance_methods", "tainted?", "=~", "private_methods", "class_variable_defined?", "nil?", "untaint", "local", "times", "constants", "is_a?", "autoload?"]
irb(main):004:0>

Saweet! By the time I read through all of that I could have found the methods nicely formatted in the API, and my eyes will be burned up anyway. So lets add a little help using the pp helper. But first we need to require it in, unless you have it in your .irbrc file, and in that case why are you still reading?

irb(main):002:0> pp Time.methods
["inspect",
 "pretty_print",
 "private_class_method",
 "const_missing",
 "clone",
 "method",
 "public_methods",
 "public_instance_methods",
 "instance_variable_defined?",
 "method_defined?",
 "superclass",
 "equal?",
 "freeze",
 "mktime",
 "included_modules",
 "const_get",
 "pretty_print_instance_variables",
 "methods",
 "respond_to?",
 "_load",
 "module_eval",
 "class_variables",
 "now",
 "dup",
 "protected_instance_methods",
 "instance_variables",
 "public_method_defined?",
 "__id__",
 "pretty_inspect",
 "eql?",
 "object_id",
 "const_set",
 "id",
 "at",
 "singleton_methods",
 "send",
 "class_eval",
 "taint",
 "utc",
 "frozen?",
 "instance_variable_get",
 "include?",
 "private_instance_methods",
 "__send__",
 "instance_of?",
 "private_method_defined?",
 "to_a",
 "name",
 "autoload",
 "type",
 "new",
 "<",
 "protected_methods",
 "instance_eval",
 "<=>",
 "display",
 "==",
 ">",
 "===",
 "instance_method",
 "gm",
 "instance_variable_set",
 "kind_of?",
 "extend",
 "protected_method_defined?",
 "const_defined?",
 ">=",
 "ancestors",
 "to_s",
 "<=",
 "public_class_method",
 "pretty_print_cycle",
 "allocate",
 "hash",
 "pretty_print_inspect",
 "class",
 "instance_methods",
 "tainted?",
 "=~",
 "private_methods",
 "class_variable_defined?",
 "nil?",
 "untaint",
 "local",
 "times",
 "constants",
 "is_a?",
 "autoload?"]
=> nil
irb(main):003:0>

Pretty cool eh? As I said a co-worker showed me the methods method some time ago and I have used it quite a bit since then. However, I often found myself having an idea of what functionality I’m searching for, therefore I can make an educated guess on what the method might be called. In this case this random list is still very inconvenient. So me being me I started looking for a method to sort the results, wouldn’t you know I found one called…SORT! Yes, amazing I know.

irb(main):004:0> pp Time.methods.sort
["<",
 "<=",
 "<=>",
 "==",
 "===",
 "=~",
 ">",
 ">=",
 "__id__",
 "__send__",
 "_load",
 "allocate",
 "ancestors",
 "at",
 "autoload",
 "autoload?",
 "class",
 "class_eval",
 "class_variable_defined?",
 "class_variables",
 "clone",
 "const_defined?",
 "const_get",
 "const_missing",
 "const_set",
 "constants",
 "display",
 "dup",
 "eql?",
 "equal?",
 "extend",
 "freeze",
 "frozen?",
 "gm",
 "hash",
 "id",
 "include?",
 "included_modules",
 "inspect",
 "instance_eval",
 "instance_method",
 "instance_methods",
 "instance_of?",
 "instance_variable_defined?",
 "instance_variable_get",
 "instance_variable_set",
 "instance_variables",
 "is_a?",
 "kind_of?",
 "local",
 "method",
 "method_defined?",
 "methods",
 "mktime",
 "module_eval",
 "name",
 "new",
 "nil?",
 "now",
 "object_id",
 "pretty_inspect",
 "pretty_print",
 "pretty_print_cycle",
 "pretty_print_inspect",
 "pretty_print_instance_variables",
 "private_class_method",
 "private_instance_methods",
 "private_method_defined?",
 "private_methods",
 "protected_instance_methods",
 "protected_method_defined?",
 "protected_methods",
 "public_class_method",
 "public_instance_methods",
 "public_method_defined?",
 "public_methods",
 "respond_to?",
 "send",
 "singleton_methods",
 "superclass",
 "taint",
 "tainted?",
 "times",
 "to_a",
 "to_s",
 "type",
 "untaint",
 "utc"]
=> nil

Now that is something useful! Can’t tell you how many times I have used this and realized the method really does exist, that is was just a spelling mistake on my part…very frustrating to say the least!

There is a great article on how to pimp out your irb here.

Why is it that I just can’t remember to close my damn tags! Is it just me or all programmers?

Sean

Posted in ,  | no comments

A Quickie

Posted by BadReligion Sat, 06 Dec 2008 12:04:00 GMT

No! Not that kind of quickie!!!

I should already be asleep but I feel like talking code. So lately I was blown away that the ActiveRecord contained a count method but ActionSupport did not. For instance to find the number of comments for each blog I ended up doing this in my controller:

@comment_count = Comment.count(:conditions => "blog_id = #{params[:id]}")

So in my blogs controller I have a class defined show that looks like this:



def show

    @blog = Blog.find(params[:id])

    @comment = Comment.new

    @ip = request.remote_ip

   

    respond_to do |format|

      format.html

      format.xml  { render :xml => @blog }

    end

  end

 

All I really need to do in my view for show is:

<%= @blog.comments.count %>

Since blog.comments actually performs an ActiveRecord find it is of that class, and therefore has the count method available.

If you are not operating on an ActiveRecord class, then what you can do instead is use the size method. For example:

@posts = [1, 2, 3, 5, 10]

=> [1, 2, 3, 5, 10]

@posts.size

=> 5

I really need to go to bed but I’m going to write tomorrow about some other fun things I’ve learned about Rails in the past couple days. Such as the lightbox plugin and more.

Sean

Posted in ,  | no comments