Computers, Open-source, Ruby, Software, Web

What will be Ruby’s Legacy?

“..Ruby has proven to be a popular evolutionary language for PHP developers. Many PHP developers are self-taught amateurs with no formal CS backgrounds. This led to a more egalitarian, “nobody knows you’re a dog” bazaar community. By contrast, hundreds of thousands of dudes with Java degrees from the cathedral on the hill saw PHP as a toy language with script kiddies brutally hacking together forums and content management systems. It wasn’t taken seriously or seen as a solution to important problems.

Well, the script kiddies have grown up, and they like Ruby now. Except, it’s pretty hard to call JRuby, IronRuby, and soon MagLev toys…”

A humorous (and great) read from ReThink

Computers, Events, Linux, Open-source, Personal, Ruby, Software, Thoughts, Web, Windows

Adventures with Rails: Part Quatre

Looking back over my previous blog entry on my Rails application, I was quite surprised to find much has changed since my last update. I suppose time flies by when you are having run right?

At this point most of my controllers have been completed. The few that are remaining should be done within the next week. So without further ado, more screenshots of this fabulous website’s slow birth:

I am up to eight modules now, with ten total expected (that means 80% done!). The work involved in creating a new “module” is trivial, so this leaves a tremendous potential for growth in the future. Who sees what module is determined by their permissions. If you have a role of at least 1, then you get to see the module’s dashboard, but not necessarily have access to each method inside of it. Permissions are delegated out per method, so it is highly adaptable.

Sending a Targeted Announcement should have been something that was a piece of cake all along. The interface that the L****** portal provides is atrocious on its best day, so we have wrapped this functionality into something a little easier to work with. The wizard will take you through a few questions to setup a population selection to target your announcement to. Interestingly, this was provided out of a training workshop for the TA API. Instead of bothering to learn it, I just copied the shell script (and corresponding Java jars) and bootstrapped it.

Above is the form to create a population selection. A SQL query editor is included with syntax highlighting, and auto-completion for limited elements. Also, ‘generic’ population selections can be filled out ahead of time on the behalf of all/other users. Part of the model validation for a pop. sel. is actually making sure that the SQL query is valid by using the following code:

protected
def validate
begin
OCI8.new(BANNER_USERNAME, BANNER_PASSWORD, BANNER_DATABASE).exec(query)
rescue Exception => e
errors.add("query", "did not parse successfully: #{e.to_s}")
end
end

This screen shows the Targeted Announcement editor complete with TinyMCE (the rich-text editor), AJAX file uploads (using responds_to_parent), and Javascript live form validation. The real showcase here is outside of the Rails platform, with the shear number of options that the TinyMCE editor has. You can drag images from the web into the textarea and it graphically renders them, allowing you to tag, resize, apply formatting, etc all without knowing HTML. From the Rails end, a technical challenge was getting the files to upload asynchronously so that changes made in the editor are not lost after the upload.

An addition to the list of modules includes a channel module that, among other things, can search for offensive content inside of the host’s file system. The idea is to keep people from posting malicious content by deterrence, and to be quickly notified by email (via the cron module) when an instance does happen. On a side note, the number of freely available offensive content lists out there are quite lacking. Most lists offer a word such as (pardon me here) “shit” multiple times with different participals, including “shits”, “shitting”, etc. Obviously, these participals can be generated on the fly using a bit of Regular Expression magic. The resulting filter looked something like this (where BadContent is a table with each offensive word as a separate record):

def self.grep_search
@delimited = []
BadContent.find(:all).each {|x| @delimited << "#{x.name}"}
"\<(#{@delimited.join("|")})(s|es|ed|ing|er|ers|in|ings|off|os)?\>"
end

As the website scaled from development to testing, and production the need to accelerate the speed of permissions management became quite obvious. I offer two solutions here in addition to manually assigning permissions for each user per component by hand. The first is a global change of the user’s permissions for all modules. The second, will allow to clone from an existing account with autocompletion available on the textbox. From a Rails standpoint, this was easily accomplished by using the respond_to method in the controller class to redirect to a Javascript template:

In the view:

document.observe('dom:loaded', function() {
new Ajax.Autocompleter('clone','clone_entries','/permission/list', {
paramName: 'username',
indicator: 'spinner'
});
});

In the controller:

respond_to do |format|
format.html { (...removed for brevity...) }
format.js {
@data = User.find(:all, :conditions => ['username like ?', "#{params[:username]}%"])
render :template => 'permission/user', :object => @data
}
end

The new cron module can be seen here displaying content from the system’s crontab via the Ruby gem cronedit. A nice feature of rails is using the script/runner functionality to run methods inside your Rail’s application from the outside – in this case in Cron. I even went as far as to generate an email via ActionMailer when these jobs are run. PS, if anyone is interested in duplicating this functionality in Microsoft Windows – I would strongly advise you that it isn’t worth the effort.

The new log module allows for ‘tailing’ system logs from the website. It isn’t a true tailing of the file (-f) because the process would never end, thus your request never served to you. Instead, I have mimiced this functionality with very short intervals of AJAX updates (you can see the spinner next to the title). Any bad keywords are automatically highlighted using Ruby’s gsub method and regular expressions, similar to the offensive content implementation above.

And the page that no programmer wants the user to see – but would be pleased to know that if it had to happen that it did so gracefully. This catchall crash handler resides in the application controller. If an unhandled exception is encountered, the stacktrace, and all parameters are saved to the database for review later. I became a believer in this implementation after I used it in another website where a user encountered an issue, notified our helpdesk, and I was given an error number and was able to completly reconstruct the environment around which it occurred – all without having ever talked to the user. (And yes Chris, now your precious passwords are MD5 hashed before being saved!)

Nothing in this post so far has even mentioned that I checked this project into Subversion, and setup a production environment (actually that part was John), and deployed my application via Capistrano. What all that means is that (without ever having to shut down my development instance) I can make a change, commit it, and then run “cap deploy” to have it pushed to our production environment.

Now the project enters beta, and hopefully I can start getting some real use out of the system with some slav… I mean volunteers. It has been a very exciting few weeks…

Computers, Events, Family, Games, Personal, Ruby, Software, Thoughts

Life is Funny like That

Life is funny when I go back into the world of programming. Writing code is a process that is incredibly detailed, but the more focused I get on a project the faster time flies by. You probably won’t believe me (becaue you might be jealous) but I lately have felt like I walk into work in the morning, take a lunch, and am on my way home before I even know what day it was.

I had lunch at the only remaining Thai restaurant within 30 miles of Clayton State University today. I have to say it was one of the best Thai meals I have ever had. If I can get up a group of people one of these days I would love to head back down that way again. (It will certaintly be one of those two-hour lunches). The special occasion today was Dolores Cox’s treat to the team that implemented L****** on campus. It was her way of saying thanks for all of the hard work we have put into it. So I get a paycheck for doing my job, and a free luch! w00t!

Tomorrow, Matt Todd is taking me out to dinner at the Four (maybe Five) Seasons restaurant and micro-brewery to celebrate his new job. He is making somewhere close to like a zillion dollars now, and whats more – he earns it by doing something that he loves. In short, he has discovered the secret to happiness. And PS – I hate you Matt Todd (but I won’t tell you until AFTER you buy my dinner).

So – people giving me free food… its nice.

Last weekend we had our annual Low-Country Boil with family and John and Anna. I had a great time (despite making myself a little sick from eating so much). I hope everyone enjoyed themselves, and sorry to John and Anna for them being the only people in a handful we invited to make it. We will do it again next year, so maybe better luck then.

All of this stuffing myself with food lately has encouraged a more lax lifestyle than I have allowed myself to partake in in quite a while. I haven’t been to the gym in over a week, and I am totally dependent on a few cups of coffee to awaken from my coma each morning. I wish there was some potion I could by that would instantly get me back in shape. (I think its called meth).

A few people have pointed out that I have yet to write about my brand new present – a Playstation 3! I really want to thank everyone for my wonderful gift. I can’t wait to see what Blu-Ray looks like 🙂

Its been busy lately, but if you have read this far in my post, then I appreciate you checking in on my life. Hence the reason I wrote this post.

kthnxbai

Computers, Open-source, Personal, Ruby, Software, Web

Adventures with Rails: Part Trois

The last few days have been particularly productive with the L****** management application I have been working on. In particular, I now have full user authentication working per method in the controllers. Authentication is done via several tables mapping users (username), roles (role), and components (components), via a permissions table (user_id, role_id, component_id). I figured with would be a daunting task to represent these relationships between the tables inside the models, but this was not the case thanks to ActiveRecord’s convention over configuration.

Inside the users model, I can make represent the relationships easily like

has_many :permissions
has_many :roles, :through => :permissions
has_many :components, :through => :permissions

Then, I can do something like:

User.find(session[:user_id]).permissions(:all)

In the above example, the user_id column in the permissions table implicitly joins the permissions table with the user’s table.

Now for some images:

The new permissions manager now easily doles our permissions for users and components. Thanks to the ActiveRecord magic above, this form is entirely constructed with a few lines of code.

The dashboard controller attempts to pull a partial template named “dashboard” from each of the controller’s listed in the components table and display its options below. Also, each of the controller’s default actions point to this template, so everything remains DRY.

The new statistics controller will pull much information from the host, including all running processes, with a search area, and AJAX periodically updating the list of processes.

One of the easier things to happen in this project has been the inclusion of Google Charts. Its API is URL driven, but as if that was too hard, Ruby has a few projects that act as wrappers for the API. I can simply run a query, and pass the results to the wrapper, and have this pretty graph draw automatically. Nice!

A very productive week I think. Now its getting close to being something I can release.