Recovering off screen windows in Mac OS X

I constantly lose windows on OS X. I think it’s because sometimes I am connected to an external monitor so OS X gets confused when I am not. I found a great solution online that I would like to re-post here so that I never have to look for it again and I can help share it with the world. All credit goes to the author of the original article.

The solution is to pop open your Script Editor and run this Apple script:

-- Example list of processes to ignore: {"xGestures"} or {"xGestures", "OtherApp", ...}
property processesToIgnore : {}
 
-- Get the size of the Display(s), only useful if there is one display
-- otherwise it will grab the total size of both displays
tell application "Finder"
  set _b to bounds of window of desktop
  set screen_width to item 3 of _b
  set screen_height to item 4 of _b
end tell
 
tell application "System Events"
  set allProcesses to application processes
  set _results to ""
  repeat with i from 1 to count allProcesses
    set doIt to 1
    repeat with z from 1 to count processesToIgnore
      if process i = process (item z of processesToIgnore) then
        set doIt to 0
      end if
    end repeat
 
    if doIt = 1 then
      tell process i
        repeat with x from 1 to (count windows)
          set winPos to position of window x
          set _x to item 1 of winPos
          set _y to item 2 of winPos
 
          if (_x < 0 or _y < 0 or _x > screen_width or _y > screen_height) then
 
            set position of window x to {0, 22}
 
          end if
        end repeat
 
      end tell
    end if
  end repeat
end tell
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Random, Software | Leave a comment

Converting Table Data to YAML for Testing in Ruby on Rails

One of my clients has a huge application with no test suite. I am helping the company migrate to Rails 2.3 as well as remove some bottlenecks from their code. I needed to convert around 10 look-up tables to YAML’s so that I could load the data as fixtures and test the application properly as I make changes. I scraped together pieces of code from the web and came up with this:

namespace :db do
  namespace :fixtures do
 
    desc 'Create YAML test fixtures from data in an existing database.  
    Defaults to development database.  Set RAILS_ENV to override.'
    task :dump => :environment do
      sql  = "SELECT * FROM %s"
      skip_tables = ["schema_info"]
      ActiveRecord::Base.establish_connection(RAILS_ENV)
      tables=ENV['TABLES'].split(',')
      tables ||= (ActiveRecord::Base.connection.tables - skip_tables)
 
      tables.each do |table_name|
        i = "000"
        File.open("#{RAILS_ROOT}/test/fixtures/#{table_name}.yml", 'w') do |file|
          data = ActiveRecord::Base.connection.select_all(sql % table_name)
          file.write data.inject({}) { |hash, record|
            hash["#{table_name}_#{i.succ!}"] = record
            hash
          }.to_yaml
        end
      end
    end
  end
end

To use, put this code in a file somewhere like RAILS_ROOT/lib/tasks/util/table_to_yml.rake and execute something like:

rake db:fixtures:dump TABLES=lookup_table_1,lookup_table_2,...,lookup_table_n
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , , , , | Leave a comment

Getting jQuery, Rails, and Authenticity Tokens to play nice

For anyone that uses the jQuery AJAX library to send POST requests to their Rails application, you have probably found that the built in Rails CSRF protection does not play nice with your jQuery POST requests. By the way, if you don’t know what CSRF is, check out my Ruby on Rails security presentation. You need to send an Authenticity Token with each POST request and jQuery does not do that for you auto-magically. This post explains how I got jQuery, Rails, and Authenticity Tokens to play nice together preventing the dreaded error:

 ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken)

Step 1: Set up an AUTH_TOKEN Javascript variable
Add this to your application’s layout file (in the head):

<%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %>

Step 2: Send the request with an AUTH_TOKEN

$.ajax({ 
            type: "POST",
    	    data:"authenticity_token="+$.URLEncode(AUTH_TOKEN),
    	    url: "http://"+HOST+"/users/login", 
    	    success: function(html){
    	        alert("woohoo!");
    	    }    	
});

One thing to note is the $.URLEncode function. I started using this jQuery plugin when I noticed “escape” and “encodeURIComponent” functions were not properly encoding the “+” character. I forgot where I found the plugin so I’ll just post it right here since it’s really lite:

$.extend({URLEncode:function(c){var o='';var x=0;c=c.toString();var r=/(^[a-zA-Z0-9_.]*)/;
  while(x<c.length){var m=r.exec(c.substr(x));
    if(m!=null && m.length>1 && m[1]!=''){o+=m[1];x+=m[1].length;
    }else{if(c[x]==' ')o+='+';else{var d=c.charCodeAt(x);var h=d.toString(16);
    o+='%'+(h.length<2?'0':'')+h.toUpperCase();}x++;}}return o;},
URLDecode:function(s){var o=s;var binVal,t;var r=/(%[^%]{2})/;
  while((m=r.exec(o))!=null && m.length>1 && m[1]!=''){b=parseInt(m[1].substr(1),16);
  t=String.fromCharCode(b);o=o.replace(m[1],t);}return o;}
});

This is the bare minimum involved to play nicely with Rails but I prefer to keep things DRY.

Step 3: DRY up your jQuery POST requests
Any good Rails programmer will notice a flaw with this solution – you have to include the authenticity token in each request. This is not DRY. You can obviously create a wrapper function but I prefer the following method:

$(document).ajaxSend(function(event, request, settings) {
    if (typeof(AUTH_TOKEN) == "undefined") return;
    if (settings.type == 'GET' || settings.type == 'get') return;
    settings.data = settings.data || "";
    settings.data += (settings.data ? "&" : "") + "authenticity_token=" + $.URLEncode(AUTH_TOKEN);
});

ajaxSend is a Global jQuery event that allows you to modify the request before it gets sent. There is one issue with the method above that caused a bit of debugging on my end. When no data is provided in your post request:

$.ajax({ 
            type: "POST",
    	    //data:"some_data="+some_data,
    	    url: "http://"+HOST+"/users/login", 
    	    success: function(html){
    	        alert("woohoo!");
    	    }    	
});

jQuery will not properly set the Content-Type of the request header. If we look at line 3522 of jQuery (1.3.2), we see the following:

if ( s.data )
				xhr.setRequestHeader("Content-Type", s.contentType);

This says that if no data is in the request, jQuery will not set the Content-Type header and a quick Firebug will show you that the browser defaults to
” text/plain; charset=UTF-8 ”
which results in Rails not decoding the authenticity token properly.

Step 4: Set the Content-Type before you POST
The easy fix is to set the Content-Type in your ajaxSend global event handler resulting in the function shown below:

$(document).ajaxSend(function(event, request, settings) {
    if (typeof(AUTH_TOKEN) == "undefined") return;
    if (settings.type == 'GET' || settings.type == 'get') return;
    settings.data = settings.data || "";
    settings.data += (settings.data ? "&" : "") + "authenticity_token=" + $.URLEncode(AUTH_TOKEN);
    request.setRequestHeader("Content-Type", settings.contentType);
});

Enjoy!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , | Leave a comment

Ruby on Rails – Skipping validations based on where object is created

I ran into an issue today where I wanted to skip validations based on where an object was created. To be more specific, I wanted to validate strictly if a “venue” was created through my web interface but I want to skip validations when importing venues. The reasoning is pretty simple, I want to require that a user provides a zip code, state, etc. if they use my web interface. However, if I import venues from a website with CRON at some frequency, I want to gather as much venue data as possible and ask users to update it later if needed.

This is not very straightforward in Rails. After all, I do not want to skip validations entirely. I ended up creating a virtual attribute for validations I wanted to skip and checking the attribute before validating:

validates_presence_of :name
validates_presence_of :country_id, :unless => "!validations_to_skip.nil? and validations_to_skip.include?('country')"
validates_presence_of :region_id, :unless => "!validations_to_skip.nil? and validations_to_skip.include?('region')"
validates_presence_of :city, :unless => "!validations_to_skip.nil? and validations_to_skip.include?('city')"
validates_presence_of :zip, :unless => "!validations_to_skip.nil? and validations_to_skip.include?('zip')"
 
validates_existence_of :user
 
# array of validations to skip
attr_accessor :validations_to_skip
attr_protected :validations_to_skip

You can put something like that at the top of your model file. Be sure to protect the virtual attribute so an attacker cannot set validations_to_skip from a web request in cases where you mass assign the model attributes.

To skip validations just do something like this when you create a venue:

v = Venue.new
v.validations_to_skip = ["country","region","city","zip"]
v.name = "A Venue"
v.user = some_user
v.save

What do you think? Anyone have a better way?

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , | 3 Comments

Back links for your Ruby on Rails application

Here is a nice little helper I wrote to display back links:

def back_link
    link_to "&laquo; Go Back", request.env["HTTP_REFERER"].blank? ? "/" : request.env["HTTP_REFERER"]
end

If you just use the HTTP_REFERER without checking if it’s blank, weird things can happen if someone lands on your page from an email, for example.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , | Leave a comment

Free Market Research Methods Part 1 – Analyzing Public Filings

Last week I attended a Market Research workshop presented by Dr. Dean Chang, Director of Mtech Ventures and Education. Instead of the general advice given at many market research presentations, Dr. Chang put himself in the shoes of a founder and walked us through some motions. This article will cover his take on analyzing public SEC filings.

Why should you bother doing market research?

  • It is expensive to develop products, but it is cheap/free to obtain research.
  • Since your product will most likely change, it is vital that you know your market so that you can successfully guide its evolution.
  • Investors and anyone with whom you may develop a business relationship will probably not take you seriously if you don’t know your market.

What is a 10-K SEC Filing?

Every publicly traded company is required to file an annual 10-K report. This document may have information on a company’s biggest competitors, distribution channels, sales figures, supply chain, and more. Some companies have their 10-K on their company website but we’ll just go to the SEC website and search for it. I use the search option “Company or fund name, ticker symbol, CIK (Central Index Key), file number, state, country, or SIC (Standard Industrial Classification)”.

*Note: While “Annual Reports” may seem to have the information we are looking for, they usually contain lots of marketing fluff and less of the data we are interested in analyzing. Make sure you see something like the following at the top of the report:
10-k_header

Three questions we should answer

  1. Who are your competitors and what are their competing products?
    (Financials, Product Differentiation, Market Strategy, Sales Channel, Resources, Investors)
  2. How big is the potential market? (1M,10M,100M,1B+)
  3. Who are your first customers and how many are there?

The Mock Company

Dr. Chang’s mock company was interested in the video game controller (peripheral) industry. We will answer some of the questions/sub-questions listed above by analyzing a competitor, Logitech’s, 10-K filing. If you search for “Logitech”, a number of filings come up but we are only interested in the 10-K.

Enough introduction, let’s get started.

What does the video game peripheral industry look like?

The 10-K has some information that helps us feel out the industry. We see the following paragraph in the “Industry Overview” section (page 6):

“We also believe that similar industry dynamics and personal peripheral device opportunities exist for non-PC platforms, such as video game consoles, digital music players and home-entertainment systems. As these additional platforms deliver new functionality, increased processing power and growing communications capabilities, we expect demand to increase for add-on, complementary devices connected to these platforms. The product expertise Logitech has developed around the PC extends to these other platforms as well and provides further opportunity for growth and leverage.”

Logitech believes that video game platforms will continue to improve, increasing the size of the video game peripheral market. This may not be ground breaking news but certainly good to hear from a market leader. Continuing to the “Digital Home Environment” section on page 7, we see this sentence:

“Logitech also offers a broad spectrum of products for gamers. We are leveraging our investments in the desktop PC to enhance gaming consoles with our expertise in force and vibration feedback, cordless connectivity, voice input and video input.”

Again, not groundbreaking given the peripherals already out on the market, but it does say that Logitech thinks highly interactive peripherals with feedback are the future.

What competing products and companies should we be aware of?

Skipping ahead to page 12 of Logitech’s 10-K, we can see that Logitech lists their major video game peripheral offerings. We should probably glance over these to make sure we are aware of what they have produced.

While we may already be aware of Logitech’s product offerings, we may not be aware of Logitech’s largest competitors in the Gaming market. On page 16, we find the following:

Competitors for our interactive entertainment products include Intec, Pelican Accessories, Mad Catz and its Saitek subsidiary. Our controllers for PlayStation also compete against controllers offered by Sony.

Obviously we will need to look at those companies if we haven’t already.

How big is our market?

Going back to the “Marketing, Sales and Distribution” section on page 13, we see that Logitech’s 2009 revenue was around $2.2 billion ( $2,208,832 in thousands ). This is great information but we need to find out what portion of that is gaming. Note that the revenue is also broken down by geographic region which is important for marketing purposes.

If we probe around for more financial figures in the 10-K, we find a very useful statement on page 42. We are given Logitech’s net sales broken down by product family. We see that for Retail – Gaming, the net sales is about $127 million. Now we know that we have at least a $100 million dollar market but probably much more since the industry was described as highly competitive and we already noted multiple competitors.

You have probably noticed that Logitech’s 2009 gaming sales decreased from their 2008 sales figure, $146 million. Continuing in this section, we see the following explanation for this decrease on page 43:

Retail sales of our gaming peripherals decreased 13% while units decreased 22% in fiscal year 2009. PC gaming sales decreased 13% with an 18% decrease in units, primarily due to lower sales of our G15 gaming keyboard and our MOMO Racing Force Feedback steering wheel, partially offset by sales of our G25 Racing Wheel. Console gaming sales decreased 12% with a 28% decline in units. The growth in sales of our GT Driving Force steering wheel were more than offset by declines in the sale of PlayStation gamepads and the Driving Force Pro steering wheel.

One piece of information we can grab from this section is that units decreased almost double the amount of sales which probably means customers are willing to pay a high premium for highly interactive peripherals.

What does our sales channel look like?

Skipping back to the “Sales and Distribution” section on page 14, we see:

“Logitech sells through many distribution channels, including distributors, OEMs and regional and national retail chains, including online retailers.” It goes on to list their third party distributors in the USA and from the “Principal Markets” section, we know that “In fiscal years 2009, 2008 and 2007, Ingram Micro Inc. and its affiliated entities together accounted for 14% of our net sales in each year. No other customers individually accounted for more than 10% of our net sales during fiscal years 2009, 2008 and 2007.”

From this information we know how they reach consumers and who their leading distributor is.

Supply Chain

Although not vital to our market research, there is good information about manufacturing in the 10-K which is important to our business strategy. On page 15, we see the following:

“To effectively respond to rapidly changing demand and to leverage economies of scale, we intend to continue our hybrid model of in-house manufacturing and third-party contract manufacturers to supply our products. Through our high-volume manufacturing operations located in Suzhou, China, we believe we have been able to maintain strong quality process controls and have realized significant cost efficiencies. Our Suzhou operation provides for increased production capacity and greater flexibility in responding to product demand. Further, by outsourcing the manufacturing of certain products, we seek to reduce volatility in production volumes as well as improve time to market.”

Here we are creating a gaming company and probably need to understand a production strategy. We may need the aforementioned hybrid model of in-house manufacturing and third-party contract manufacturers to supply our products. The above information should also raise a few questions. Is Suzhou, China the best place in the world to develop video game peripherals? If so, why is Suzhou the best? Maybe Suzhou is just really cheap, or maybe manufacturers in Suzhou specialize in these devices. I’m not sure the reason but it’s worth looking into.

Acquisitions

Another thing to look for in a SEC filing is acquisitions. Getting your technology bought out by the market leader for a large sum of money is obviously a nice exit strategy. Access to an exhaustive list of acquisitions conveniently starts on page 83 of the 10-K. You may want to read a little about the companies to understand what types of companies Logitech is interested in acquiring.

Conclusion

The purpose of this blog post was to demonstrate that 10-K’s can provide a good starting point for your market research. Much of the information is basic, but it is all free information and held to a high standard with regards to accuracy.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in marketing | Tagged , , , , | 2 Comments

Where is my crontab located on Mac OS X 10.5 Leopard?

I googled around for a few minutes with no luck. After probing around my system, here is where I found my crontab file:

Macintosh-2:mls TAmoyal$ sudo ls /usr/lib/cron/tabs/
Password:
TAmoyal

I found it by checking the crontab man page:

man crontab

Where I saw a “FILES” section:

FILES
     /usr/lib/cron/cron.allow
     /usr/lib/cron/cron.deny

And that lead me to probe around the /usr/lib/cron directory. Note that you can view your crontab my with:

crontab -l

but I wanted to view the actual file for debugging purposes.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Random, Software | Tagged , , , , | Leave a comment

Interning empty string error in Ruby on Rails

I don’t like writing short posts about fixing code errors but I think this one deserves a quick shout out. If you get an error in your Rails application that says “interning empty string”, there could be something wrong with an error message in your validations. For example, I had something like:

def geocoding_works_when_geotarget_is_true
    if geotarget and (self.lat == nil or self.lng == nil or self.address_changed?)
      errors.add("Provide better location information so that we can geotarget your reminders.") unless geocode
    end
end

The ‘.’ in my error message caused an “interning empty string” error. I hope I save someone an hour by posting this.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , | 5 Comments

Logging your Rails model (the easy way)

In one of my Rails applications, I have some pretty heavy tasks in my models. I decided to log to different files for two of my models so that I can easily make sure these tasks are performed correctly without going through my application log. I also call some of my model methods with rake tasks so it’s nice to have that action logged. The code below implements a custom log for the SomeClass model.

class SomeClass < ActiveRecord::Base
     LOGFILE = File.join(RAILS_ROOT, '/log/', "someclass_#{RAILS_ENV}.log")
 
     def self.do_something
          log "I am doing something"
     end
 
     def do_something_else
          SomeClass.log "Tried to do something else, but screwed up.", :error
     end
 
     def self.log(message, severity = :info)  
         @model_log ||= ActiveSupport::BufferedLogger.new(LOGFILE)
         @model_log.send severity, "[#{Time.now.to_s(:db)}] [#{severity.to_s.capitalize}] #{message}\n" 
     end
end

This will create separate logs for all of your environments. Notice that I reference the class when I log from an instance method. This is working great for me. Anyone have a better way?

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , | Leave a comment

Validating multiple fields with one validator in Flex3

I like laying out forms in MXML because it’s easy to read. In a recent project, I had five email fields and it looked something like this:

<mx:Form id="myForm">
	<mx:FormItem label="1." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email1" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="2." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email2" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="3." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email3" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="4." labelStyleName="tenEmailsLabel">
	        <mx:TextInput id="email4" width="300" fontSize="13" />
	</mx:FormItem>
	<mx:FormItem label="5." labelStyleName="tenEmailsLabel">
		<mx:TextInput id="email5" width="300" fontSize="13" />
	</mx:FormItem>
</mx:Form>

I obviously wanted to use one validator for all of the email addresses since they all need to be validated the same way. I couldn’t find any great examples on the internet so I am posting the code to validate multiple fields with one validator.

private function submitForm():void{
     var result:ValidationResultEvent;
     var isValid:Boolean = false;
 
     for(var i:int=1; i<myForm.getChildren().length; i++){
	tenEmailsValidator.source = this["email"+i];
	result = tenEmailsValidator.validate();
	isValid = isValid && ( result.type == ValidationResultEvent.VALID )? true : false;
     }
 
     if(isValid){
	//...submit the form
     }else{
	 Alert.show("You cannot submit the form with errors.");
     }
}

If anyone has a better way to do this, please share!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , | 5 Comments