Computers, Personal, Ruby, Software, Thoughts

The Woes of Work

This week it seems that I have developed programmer’s block. I don’t know if there is such a thing, but I have felt totally unable to do anything involving code. I can’t write SQL, I can’t write Ruby, and I can’t even think through concepts that my co-workers are proposing.

It probably doesn’t help that my co-worker wanted to share the same development database instance “since there are only two of us, what could possibly happen?”, and he has been migrating my ass to death. Also, with constant foundation changes, my code literally breaks every night. It also probably doesn’t help that no one likes my solutions before I even have time to flesh them out into a prototype. And the final nail in the coffin is the constant interruptions in my day from supporting everything else that we do.

When I code, I have a tendency to go with the simplest possible solution to a problem. Generally, this means less code, less bugs, and the least surprise to the end user. This also generally requires less effort. This week I have felt like someone running beside a train in which my co-workers are comfortably sitting, discussing some pretty “out-there” solutions, and I am gasping for air, and reaching up trying to grab onto anything to pull myself onboard.

I would love to develop this project in an agile way. This isn’t just some methodology written on paper – it is a mindset that you have to embrace. In part- if you build your foundation in an sensible and orthogonal way (from The Pragmatic Programmer),  then the problems of tomorrow don’t account for your design today. However, my co-developers want to build the beginning code with this grand vision of the end baked into the first lines of code. I am not ready to field questions about how ‘x’ is going to fit into ‘y’ in some scenario yet. I haven’t even written ‘x’ and ‘y’.

Our boss finally said on Thursday that he is going to remove the deadline on our project, so that we can take our time. Initially I was pretty upset, because when projects get put on the back burner, we rarely move them back to the front again. However, in my current state maybe it is for the best.

Maybe I just need a vacation…

Apple, Computers, Linux, Open-source, Personal, Ruby, Software, Thoughts, Windows

Netbeans 6.5 Rails Console

I was really excited about the release of Netbeans 6.5. It is the only solid Ruby  / Rails IDE that I know of, and it runs circles around Aptana (aka RadRails). Among the new release features is an integrated Rails console. This means that I can develop and test all in the same app without having to ALT+Tab myself to death.

Let me preface this rant by saying that I have the utmost respect for Netbeans (despite its owner) – it is rock solid, easy to use, and powerful. However, the Rails console leaves much to be desired. Here is my list of issues that I would love to see addressed (by someone with more Java finesse than myself):

  1. The Rails console doesn’t allow pre-typing. The environment may take 1 – 30 seconds to load. In this time, I should be able to start typing in my command and have it fill-in correctly once the prompt is available. It will fill in all the stuff I type before it is ready in a random order instead.
  2. The “Up” arrow on the keyboard moves the caret to the previous line, unlike in IRB / console / Bash where it should autocomplete the previously run command
  3. Ctl + L will clear the screen, just like in the development logs, and console on Linux / OS X, but it actually renders the console useless. It removes your prompt, and stops accepting keyboard input

While someone is at this, here are some of my dream features:

  1. The same code-completion that is provided by the IDE itself. If I type in a model name, and hit “.”, it should show me a list of instance methods on that model.
  2. Syntax highlight the output just like in the IDE

Please Netbeans community, Christmas is coming – consider it a gift to the world!

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

SWAN Manager v2.0

It has been a trying last few weeks, but I have finally rolled out the new SWAN Manager. It ended up being almost a total rewrite, and I walked away with a lesson learned:

  • Even on a total rewrite, I should have consistently been checking in my code at “checkpoints”. Instead, I waited until everything was working, then did one single massive checkin. Inevitably I missed stuff, forgot to cleanup stuff, and had to resolve a couple of SVN conflicts where it just didn’t understand what the hell happened.

I have highlighted a few of the more significant changes in screenshots below:

I based the new login screen off of Google Docs login. It shows at a glance what services are offered inside the Manager, and is a little more friendly than just a login box. Also, you can see the new tabbed interface at the top.
The User model underwent the most significant of changes. First, I decided that it was running way to slow, so I reimplemented the way it looks up the data from an indirect (and unreliable) method, to querying the sources directly. Also, the data is cached using memcached for even more speed enhancements.

An area I am particularly proud of is the display of the icons the user should see. I take each role name, and do a Net::HTTP fetch on them, checking for a 200 result, and displaying it. This is all handled in a helper.

The channel model underwent significant changes as well. It has always directly queried for the data on each request, instead of caching the results. In addition to caching and other performance tweaking – I now know a lot more about the channels themselves. The entire model operates as an “acts_as_tree” with parent, and children nodes to show the sections, and sub-sections of a channel. If you can edit a section, it shows up as a link.
The announcements controller has been completely reworked as well. Before the user didn’t have the ability to do things like send to a role, or choose delivery / expiration times, or a destination. Now the user gets to pick all of this (Population Selection with a parameter is shown). A message can be sent with just a few clicks. The announcement model uses “acts_as_state_machine“, a seemingly dead but very useful plugin. The announcement goes through several states with validation checking and routing automatically handled. I have to thank Matt for turning me onto the idea.

Here I have an image of the announcement wizard further down on the same page as the image above. The date selected is handled by a Rails plugin called “unobtrusive_date_picker“. It allows some cool tricks like keyboard arrow navigation, and the ability to define starting / ending date ranges, and minute increments in the select box.

Additionally, once the announcement is sent, rather than going to get a cup of coffee while it runs the process (sometimes 10+ minutes), it now backgrounds it in a separate rake task.

All in all, I think that this is a word of difference from the previous SWAN Manager. This is stable, fast , and easy enough now that I feel it is something the campus as a whole can use without concern.  And it will need to live up to it expectations as well, as we have a few departments already lined up to start using its functionality as soon as we give the green light.

After I pat myself on the back, I suppose its time to get back to working on all those pesky channels…

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.