Cookie Detection in Rails 3

April 23rd, 2013

I have seen a lot of posts on cookie detection in Rails. I believe this may be a bad idea, in general, but here is a cheap way to detect whether or not cookies are enabled in the browser. Just add a before_filter that checks for the presence of the application’s cookie.

  1.  
  2. class ApplicationController < ActionController::Base
  3.  
  4.   before_filter :check_cookie
  5.  
  6.   …
  7.  
  8.   private
  9.  
  10.   def check_cookie
  11.     cookie_name = Rails.application.config.session_options[:key]
  12.     if request.cookies[cookie_name].to_s.blank?
  13.       flash[:error] = "To use this site, you must enable cookies in your browser’s settings."
  14.     end
  15.   end
  16.  
  17. end
  18.  

..And Voila! Now if your users try to view any page, they will see a nice Flash message about their cookies!

Building a unified time_select field, with simple_form

April 10th, 2013

Before I migrated to Rails 3.2, I used a plugin to provide a unified input field for time_select with either the standard Rails ActionView or the SimpleForm gem (SimpleForm uses ActionView under the hood). I was happy until the Rails upgrade caused my gem to inexplicably stop working. I had a deadline to meet and could not be bothered with complicated solutions. I searched and searched for alternatives to this fine gem, but none were found. Then it hit me: why not just write my own code and replace the inputs with my own code? Surely it can’t take too long to build a time input based on the simple_time_select gem! So here it is: my simple version of the gem, with only a few modifications from the simple_time_select gem.

Here is my old code, utilizing simple_time_select. The gem is used only if :simple_time_select is true, and it uses the :minute_interval, :time_separator, :start_hour, :end_hour, and a host of other options for setting the times. I wish it had a way for specifying just a start_time and end_time.

  1. <div class="field">
  2.   <%= f.input :start_time,
  3.               :label=>"Start Time:",
  4.               :default=>appt.start_time,
  5.               :wrapper=>false,
  6.               :simple_time_select => true,
  7.               :label_html=>{:class=>"head"},
  8.               :minute_interval => 5,
  9.               :time_separator => "",
  10.               :start_hour => 06,
  11.               :end_hour => 17
  12.    %>
  13. </div>

I had to search for an algorithm to use for the periodicity, and settled on the algorithm discussed in this discussion on Stack Overflow, and is inlined as the :collection option. Since the :default option removes the inital blank I wanted as the first item in the list, I has to add a blank :include_blank option.

  1. <div class="field">
  2.   <%- time_start = Time.now.change(:hour=>6,:minute=>0) %>
  3.   <%- time_end = Time.now.change(:hour=>17,:minute=>55) %>
  4.   <%- period = 5.minutes %>
  5.   <%= f.input :start_time,
  6.            :as=>:collection_select,
  7.            :required=>true,
  8.            :include_blank => ,
  9.            :selected=>(
  10.              f.object.start_time.blank? ?
  11.                "" : f.object.start_time.strftime("%H:%M")
  12.            ),
  13.            :input_html=>{
  14.              :name=>"appt[start_time(5i)]",
  15.              :id=>"appt_start_time_5i"},
  16.            :collection=> (
  17.              [time_start].tap{
  18.                |array| array << array.last + period
  19.                  while array.last < time_end
  20.              }).map{
  21.                |t| [t.strftime("%l:%M %p"), t.strftime("%H:%M")]
  22.              }
  23.    %>
  24. </div>

I am sure you can wrap this in a Helper class somewhere, and it should be easy to monkeypatch ActiveView or SimpleForm to display this instead of the default.

References:

Simple Rails Development Part I: Gedit Click Config

August 30th, 2012

After evaluating all editors and IDEs I could ahold of for Ruby On Rails development in Linux, I decided none were really up to my expectations. I was really looking for something as powerful for Rails development as Eclipse is for Java development. Unfortunately, there were not any. Most of them were close, but all lacked some key ingredient necessary to make my life a little easier. However, I did find a great solution which required learning a little more about an undiscovered basic text editor in Fedora: GEdit. In order to make my rails development a little easier, I installed a few plugins, but only one of them took me by surprise: Click Config.

NOTE: This article is written for GEdit 3+. A simple Google search will yield many articles for Gedit 2.

Most IDEs and editors have different functions when multi-clicking in an editor pane. Most of them have the following selection actions:

  • Single-Click: Move the editing cursor to the mouse cursor’s location
  • Double-Click: Select the word that is under the mouse cursor
  • Triple-Click : Select the entire line that is under the mouse cursor

Only a few editors have a quad-click option for selecting an entire paragraph. GEdit Click Config not only has a quad-click option, but has a quit-click (five clicks in quick succession) option as well. Amazing! Not only can you configure what click-types are available in GEdit, but you can configure the click parameters based on a given regular expression (“regex” for short). And to top it all off, you can configure which click options are activated based on what language GEdit is set to.

I Gotta Have It!

I have not found a distro yet which ships with GNOME and does not have GEdit as well, so it should be in your local *nix distro’s repository or already installed it.  If you don’t have it already, you can pick it up at http://code.google.com/p/gedit-click-config/, and it doesn’t require root access, so setup should be really simple, just follow the directions.

You mentioned Ruby on Rails?

Yes… yes I did.  You can find out more about Ruby words, constants, and other things here. Ruby words are pretty simple: they:

  1. can begin with a single $ sign 
  2. can begin with a single or double @ sign, a
  3. can contain any letter a-z, case insensitive

I like to add a fourth rule, just for constants, because when i select a part of a constant, i want the whole thing: can contain two colons in a row.

To put all that in simple regular expressions: ((\$?)|(@?@?))([_a-zA-Z]+(::)?)+. I am sure you can write that in a thousand different ways, but that is the one I like best, because it is really clear what is going on. Also – the matches almost line up at \2,\3,\4.\5 This regex should be newly defined in the Click Config settings. You can get there by menu, at Edit->Click Config->Configure. You can create a new selection rule by adding it in the only editable inoput field at the bottom, clicking the “Add” button and entering a name for it. I suggest using “Ruby Word” for the name.

I also find myself moving ruby strings around a lot. Wouldn’t it be great if you could just triple-click and select the entire string? With GEdit Click Config, you can! All you have to do is create a new selection rule, with the following regular expression: (['"]).*?\1. Make sure to check the ‘M’ flag to the right of the input field, in prder to make it multi-line, if you wish. To break down the pattern, the first paren matches either single- or double-quotes. Then match anything until you get to the next single- or double-quote. The ‘\1′ means to match the value from the first parenthetical match, so the quotes will line up properly. The ‘.*?’ means to match anything, but only until the next regex portion matches. If we leave out the question mark, we will match anything until the last next-character match, This is called a non-greedy search, and is necessary for this type of pattern-matching.

Come Together

I hope you learn to enjoy some of the basics as I have. To close this entry out, I will list all the Click Configs I have for all my Languages:

Selection Rules

  • Ruby Word: ((\$?)|(@?@?))([_a-zA-Z]+(::)?)+    (Flags: None)
  • Full Quote: (['"]).*?\1   (Flags: M)
  • Single-Line Quote  (Flags: None)
  • Haml Word: (\.|\#|\$?|(@?@?))([_a-zA-Z]+(::)?)+

Inline input fields with mnimal jQuery

May 25th, 2012

For one of my projects, i needed to put a text field inside a header element. When I did so, the input field ruined my layout and good looks! So I went the jQuery way and devised a method for hiding inputs when not in use, but when clicking on it, turns into a normal input field. So in my CSS, I add:

  1.  
  2. input.hidden{
  3.     color: inherit;
  4.     padding: inherit;
  5.     margin: inherit;
  6.     border: none;
  7.     background: transparent;
  8.     font-size: inherit;
  9.     font-weight: inherit;
  10.     font-family: inherit;
  11.    
  12. }
  13. h2 {
  14.     color: #648dd7;
  15.     font-size: 18px;
  16.     font-weight: normal;
  17.     margin-top: 16px;
  18.     margin-left: 2px;
  19. }
  20.  

and in my html, I have:

  1.  
  2. <h2>Header<input name="myInput" value="[Header Input]" class="hidden"/></h2>

And here is the fun part. Essentially one line of javascript to accomplish this easy feat:

  1.  
  2. $(‘input.hidden’).live(‘focus’,function(){
  3.     $(this).removeClass(‘hidden’).live(‘blur’,
  4.                                        function(){$(this).addClass(‘hidden                                                                                              ’)})})​;
  5.  

jQuery ThemeSwitcherTool – Working Version!!!!!

March 6th, 2011

I recently tried to install the jQuery UI  ThemeSwitcher on a site for a project on which I am working. It failed. Miserably! I scoured the interwebs for a working version, but could not find one anywhere. However, I did find out why the tool was not working. It seems the jQuery team disabled hotlinking to its servers. This was extremely good news, as it meant I could simply recode the widget to point to the new files or download them and point the script to the downloaded files. I dove right in to the code and made some modifications to the start of the script. Then I optimized some of the rest of the code. Finally, I added a few extra options to cover the changes I made.

Download

You can click on the following links to download the files.

  • themeswitchertool.js – The themeswitcher.
  • The Following files are images used by themeswitcher. To use them, place them in /javascripts/jquery/themeswitcher/ or use the imageLocation option to point to the directory where these are stored.

Changes

  • The old script appended up to three styles to the document, then removed the first one. It now uses the selector “head link#ui-theme” to change the stylesheet. I changed this so you can set the id of your default custom theme to “ui-theme” and it will change this. If the id isn’t found, it creates a new one.
  • Added new options for specifying your own themes to add to the list.
  • Added new option, useStandard, for specifying whether to use the themes from the jQuery UI site.
  • Added new options for specifying where to find the UI icons and stylesheets
  • Added new option, imageLocation, for specifying where to find the widget images (found in the downloaded file)
  • Added the widget images to the downloaded file, so you don’t have to link to jQuery’s servers
  • Added option, useCookie, for whether to use a cookie for saving the theme for later use on the same page.

Examples

Basic usage, no custom theme support

  1. $(‘<div id="theme-switcher"></div>’).prependTo(‘body’).themeswitchertool( );

Adding custom themes

  1. $(‘<div id="theme-switcher"></div>’).prependTo(‘body’).themeswitchertool( {
  2.     themes: {
  3.        ‘theme1′: {
  4.            icon:"/path/to/theme-icon.png",
  5.            css:"/path/to/theme.css"
  6.        },
  7.        ‘theme2′: {
  8.            icon:"/path/to/theme2-icon.png",
  9.            css:"/path/to/theme2.css"
  10.        }
  11.     }
  12. });

Using Only Custom Themes

  1. $(‘<div id="theme-switcher"></div>’).prependTo(‘body’).themeswitchertool( {
  2.     useStandard: false,
  3.     themes: {
  4.        ‘theme1′: {
  5.            icon:"/path/to/theme-icon.png",
  6.            css:"/path/to/theme.css"
  7.        },
  8.        ‘theme2′: {
  9.            icon:"/path/to/theme2-icon.png",
  10.            css:"/path/to/theme2.css"
  11.        }
  12.     }
  13. });

New Options

themes
Default: {}
A hash of themes, where each key is the theme name, and the value is another hash specifying the icon to use and the css file for the theme. Here is an example:

  1. {
  2.   ‘theme1′: {
  3.     icon:"/path/to/theme-icon.png",
  4.     css:"/path/to/theme.css"
  5.   }
  6. }
useStandard
Default: true
If you don’t want the themes from the jQuery UI site to show up in the list, set this to false.
useCookie
Default: true
The Theme Switcher uses a browser cookie to store and retrieve the theme name for the current site. Set this option to false if you do not want your site to remember the theme.
imageLocation
Default: “/javascripts/jquery/themeswitcher/”
This is where the images are stored which Theme Switcher uses. The following files must be in the folder: buttonbg.png, icon_color_arrow.gif, menuhoverbg.png . You can get these from the download.
imgPrefix
Default: “http://static.jquery.com/ui/themeroller/images/themeGallery/theme_90_”
This option specifies the default icon prefix URI. The icons are the previews for each theme. The default option sets the default images to the jquery hotlink site. This may change in the future, so it is specified here as an option.
imgSuffix
Default: “.png”
This option specifies the rest of the image URI.
cssPrefix
Default: “http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/”
This option specifies the deafault css location prefix.
cssSuffix
Default: “/jquery-ui.css”
This option specifies the deafault css location sufffix.

Tango Icons: Save All

July 28th, 2010

Ever notice how the  Tango icons don’t have a “Save All” icon? Well – look no further! I have created a usable set, using the existing icons as a template, all in about 15 minutes. So – without further ado – here they are:

16x16 Tango Save All icon

16x16

Tango Save All icon - 22x22

22x22

Tango Save All icon - 32x32

32x32

I did not create these for real polish – I just needed something on-the-fly, but if you have any suggestions on making them better, please let me know!

Also – if you would like a zip archive so you can just unzip them into the existing tango folder – here it is: tango-icon-save-all

New Theme Under Construction…

July 31st, 2009

Hello, all RBS followers! I am creating a new theme for WordPress called Bubbly Blue, which is part of my Bubbly Blue theme series. So far I have only one other – an Ampache theme. I am using this blog as a testing area for this theme, so please be patient if something goes horribly awry!

Thank you all!

Updated August 9:

Here are some features of my theme so far:

  • Three-Layer Header for more customization! = The background layer is for gradients, etc. The Logo layer is for your logo. The FX layer is for added graphics to enhance the other layers.
  • A top menu, which can show all pages as tabs. Also doubles as a sidebar.
  • Three sidebars: one dropdown menu and two sidebars on either side of main content area. These can be turned on/off in the options panel.
  • W3C standards-compliance. A graphic link has been added to the footer so you can just click to test
    the validity of each page.

My theme is almost complete! Still left to do:

  • Move header text over when logo is enabled/disabled
  • Fix Comments/Respond tabs on posts
  • Create Default sidebar widgets if dynamic widgets are not available
  • Add login form to header/sidebar and add option for which to use.
  • Resize content area when sidebars are turned off.
  • Curve corners of header, footer and sidebars
  • Sort Through and optimize Stylesheet
  • Ajax-ify Comments
  • Three-Layer header options panel.
  • Remove unused php files / consolidate php files
  • Cleanup code!
  • More Testing!

How To Repair Images with ImageMagick

June 15th, 2009

I have been doing a lot of importing of photos on my photo site, and have noticed some images do not display properly. SinceI love ImageMagick so much,  I set up  my gallery to use it. However, there appears to be a check in the Coppermine software that aborts reading the file upon errors in the image. So I typed the command “display imagename.jpg” for some of the files that did not import properly, and everything appeared to be fine. But I did notice something peculiar about the images: they were taken with my phone’s camera and all had errors printed out when I tried to open them, but seem to display correctly.

Since these files could be opened by ImageMagick, I figured if I saved them again, I would be able to fix the errors. I ran “convert image1.jpg image1.jpg”, got the familiar errors printed and opened the file again. This time, no errors! But since I have a  lot of files I want to import, I needed a way to convert a bunch at once.

I created a neat little Perl script to do just that. All you need is ImageMagick and perl installed. This script does not rely on PerlMagick, as it runs the convert command. So here it is:

  1. #!/usr/bin/perl
  2.  
  3. processFile("$_") foreach (@ARGV);
  4.  
  5. #recursively fix images
  6. sub processFile {
  7.    my $file=shift;
  8.    return (-d "$file")?( do{ processFile("$_") foreach (<"$file"/*>) }) : `convert "$file" "$file"`;
  9. }

I saved this file as $HOME/bin/fiximage. All you need to do to run it is type “fiximage file1 file2 directory1 directory2 …”. One other thing to note is that this script has been purposefully shortened. I like to use the ternary operator whenever possible in my scripts for just this reason. As such, it does not print anything to the command line itself, but if the convert command encounters an error, that will be printed.

I hope you have found this article useful!

Fun With Numbers!

May 29th, 2009

I have always had a certain love for math and the neat things you can do with it. Here is a bit of information and shortcuts I have picked up in a few of my math classes.

Pascal’s Triangle

Pascal’s Triangle is a pretty neat thing. It is very simple to construct and can be used to understand a lot of different ideas. It follows a very simple form: start with a ’1′ and add the two digits above  to get the next number. The first few line look like this:

1
1  1
1  2  1
1  3  3  1
1  4  6  4  1
1  5 10 10  5  1
1  6 15 20 15  6  1

The line numbers start at 0, and continue on ad infinitum. In order to generate this triangle, programmatically, you would use something like this:

  1. vector<int> pascal(
  2.       vector<int> prev, //the current (old) row data
  3.       int *len,           //the length of the data
  4.       int end,                    //the row to retrieve
  5.       int cur=0           //the current row we are on
  6.       );
  7.  
  8. vector<int> pascal(vector<int> prev,int *len,int end,int cur){
  9.  
  10.        //return immediately if we are at the last row
  11.       if (cur==end) return prev;
  12.  
  13.            //if the current vector length is 0, then set it to 1
  14.           if (*len==0) *len=1;
  15.  
  16.           //create a temp vector (all 1′s) to store the new row data
  17.           vector<int> t((*len)+1,1);
  18.  
  19.           //sum the two rows
  20.           for(int i=1;i<(*len);i++)
  21.             t[i]=prev[i-1]+prev[i];
  22.  
  23.           //increase the length by 1
  24.           *len=(*len)+1;
  25.  
  26.           //return the new row data
  27.           return pascal(t,len,end,cur+1);
  28.  
  29. }

Binomial Expansion

Remember binomials from algebra? They were the pair of numbers used to create or simplify polynomial expressions, something like:

( x + 3 )^3 = x^3 + 9x^2 + 27x + 27

You can use Pascal’s triangle to find the coefficients of the polynomials. Let’s begin by solving for the generic case:

(a+b)^n =
(a+b)^{n-1}(a+b) =
(a+b)^{n-2}(a+b)^2 =
(a+b)^{n-2}((a+b)(a+b)) =
( (a*a) + (a*b) + (b*a) + (b*b) )(a+b)^{n-1} =
(a^2+2ab+b^2)(a+b)^{n-1} =

See the coefficients so far, with n=2 ? They are [1 2 1], which corresponds to the second row in Pascal’s triangle. But this could be a fluke, right, so let’s jump ahead to n=5 to see if that works as well.

(a+b)^n =
(a+b)^{n-6}(a+b)^5 =
(a+b)^{n-6}( (a+b) (a+b) (a+b) (a+b) (a+b) ) =
(a+b)^{n-6}( ( (a+b)(a+b) )( (a+b)(a+b) ) (a+b) ) =
[we know what (a+b)^2 is, so: ]
(( a^2+2ab+b^2 )( a^2+2ab+b^2 )(a+b) )(a+b)^{n-6} =
( ( (a^2*a^2)+(a^2*2ab) + (a^2*b^2) + ( 2ab*a^2) + (2ab*2ab) +
    (2ab*b^2) + (b^2*a^2)+(b^2*2ab) + (b^2*b^2) ) (a+b) )(a+b)^{n-6} =
( ( a^4 + 2a^3b+ a^2b^2 + 2a^3b + 4a^2b^2 + 2ab^3 + b^2a^2 + 2ab^3+ b^4) (a+b) )(a+b)^{n-6} =
( ( a^4 + 4a^3b + 6a2b^2 + 4ab^3+b^4) (a+b) )(a+b)^{n-6} =
[note: notice that the coefficients of (a+b)^4 are (1 4 6 4 1) ! ]
( ( a^4*a + a^4*b + 4a^3b*a + 4a^3b*b + 6a^2b^2*a + 6a^2b^2*b + 4ab^3*a + 4ab^3*b + b^4*a+b^4*b))(a+b)^{n-6} =
( ( a^5 + a^4b + 4a^4b + 4a^3b^2 + 6a^3b^2 + 6a^2b^3 + 4a^2b^3 + 4ab^4 + ab^4+b^5))(a+b)^{n-6}=
( ( a^5 +5a^4b + 10a^3b^2 + 10a^2b^3 + 5ab^4 + b^5)(a+b)^{n-6}

There it is! The coefficients correspond to the rows on Pascal’s Triangle!

Features

Now, to make things a little simpler, I will note some interesting “features” about what we just did.

General Formula for Binomial Expansion

The general formula for binomial expansion is:

(a+b)^n = \sum_{i=0}^{n}(P_{ni}a^{n-i}b^i)

Where P_{ni} is the coefficient at row n (starting from 0) and column i in Pascal’s Triangle. The formula means to add from i=0 to n all the terms (P_{ni}a^{n-i}b^i) , replacing i with the number you are at. For example, supposing i=3, you would get:

\sum_{i=0}^{3}(P_{3i}a^{3-i}b^i) =
(P_{(3,0)}a^{3-0}b^0) + (P_{(3,1)}a^{3-1}b^1) + (P_{(3,2)}a^{3-2}b^2) + (P_{(3,3)}a^{3-3}b^3) =
since P_3 = [1 3 3 1] , we finally get:
((1)a^{3-0}b^0) + ((3)a^{3-1}b^1) + ((3)a^{3-2}b^2) + ((1)a^{3-3}b^3)
cleaning up a bit :
a^3 + 3a^2b + 3ab^2 + b^3

Exponents

Note in all the expansions, the first variable counts down from n to 0, while the second variable counts up from 0 to n.

Does your binomial already have coefficients?

If your binomial already has coefficients, simply add the coefficient in with the variable it is with, so it merely multiplies the term by that amount. For example:

(3a+b)^3 =

TeTex for Puppy Linux

May 10th, 2009

SORRY!: The current sfs file is broken. I am working as fast as I can to fix this, so check back for more!

I have recently had to send my new laptop back for a power board replacement, so I have resurrected my old laptop. It is a HP Pavilion ze4900 that my coworker gave me 2 years ago. (It was an old one he didn’t want.) This laptop was pretty old when I got it, and a series of unfortunate events occured.

First, the power cord got fragged. Then the battery died. Lastly, the hard drive failed. With all these problems, there was only one solution: a small, lightweight linux distro to use as a dumb terminal for my server. So I installed Puppy Linux on a CD, ran it with a USB drive and worked on my Summer of Code project with it. I loved Puppy Linux!

Since I am now in that same position, I have decided to update my version of Puppy from 4.00 to 4.20. I also found out that without a hard drive even attached, this laptop will boot from a USB drive. Since I now have a 8 Gb drive and plenty of space, I decided to install a few extra programs, including the development .sfs file, which allows me to build software for this excellent distro!

I really wanted tetex and a good editor, but don’t really like installing pups/pets. I prefer sfs files, so I can have better control over what is installed and how it is installed. So I got down to it!

I went over to the the Puppy Linux forum to find out how to make sfs files, and found a great tool here. Then I downloaded tetex and texmf, compiled it in /usr/local/tetex, and created this sfs file. To use it, just put it in the same location as your pup_save.2fs file and reboot. If you want to use it with other versions of Puppy Linux, change the 420 in the filename to 400 or 300 or whatever the standard is for your version.

I am also working on incorporating several tex editors with it, so keep checking back for more!