Wednesday, October 27, 2010

My first regular expression!

I was working on a project yesterday that required some string validation. I had a vague sense of regular expressions, but never used them. I thought this might be a good chance to get my feet wet.

I needed to validate that a store name contained only letters, numbers, spaces or apostrophes. I didn't want any spaces before or after the store name and only single spaces between words in the name. I could probably get the job done with other string functions, but I knew regular expressions would be cleaner...a lot cleaner.

I did a little searching and came across this post, http://www.bennadel.com/blog/769-Learning-ColdFusion-8-REMatch-For-Regular-Expression-Matching.htm, by Ben Nadel and decided to give REMatch a try. I won't lie, it took me two hours to finally write the regular expression that did what I needed.

<cfset regexname = REMatch("(^( )[A-Za-z0-9]+)|([A-Za-z0-9]+(  ))|(  )|(( )$)|[^A-Za-z0-9 ']","#storename#")>


This function will return a variable, regexname, as an array. I check the array with ArrayIsEmpty(). If that function is true then the store name is valid. You see, the array would contain something if the REMatch function found an occurrence in  #storename# that matches one of the regular expressions. I actually wrote a group of regular expressions. There are 5 and they are separated by a pipe(|). The pipe character means OR. So what I end up with is a regular expression conditional statement.

Monday, June 28, 2010

New Painting with a Bit of an Edge

I did a painting last night that's a little different than my other ones. We stopped at a beach on the Lake Michigan shoreline on our way back from Petoskey, MI. I snapped some photos with nothing rerally intended for them, just snapshots. While reviewing my photos this one jumped out at me as one that I wanted to work with. There is another one too, but this one looked the most fun.

I spent about 5 hours with the painting and I thought I was almost done. But something wasn't quite right. I don't know, it looked too plain. I saw a technique a while ago used by Android Jones; just going crazy with the straight line tool. After about 10 minutes I zoomed out and thought it actually loked pretty good. I spent another 2 hours just adding lines. I then added some elements in this style to the sky to tie it together. It's called "Let's Pull Over Here" and can be seen bigger (and purchased :) on Etsy: http://www.etsy.com/listing/50351213/lets-pull-over-here-8x10-fine-art-print.

Thursday, June 24, 2010

My Rhino on Tumblr



I was looking through my Analytics today and saw that Etsy tumbled my Rhino! http://etsy.tumblr.com/post/657466802

Friday, May 28, 2010

Facebook single sign on with Coldfusion

I'm working on a project site that allows people to share stories of events, places and people. I'm still fleshing it out, but I got the idea that I wanted to integrate it closely with Facebook. Vistitors will be able to log in with their Facebook account and have access to all their FB photos and videos to share on my site. Needless to say, a FB sign on would eliminate a visitor's need to create and remember one more account on another site.

FB makes it pretty easy using PHP, but I've never liked PHP. That discussion is for another post...let's just say Coldfusion is more fun. I'm not a CF expert. I might still place myself in the beginner level. However, with just a little more than an hour of translating their PHP code to Coldfusion I was able to get a working example. It was pretty cool to display Facebook stuff on my page. I'm still working on my localhost so I can't show an example, but I'll post the code below.

As I said, this is a project site and I'm still in that "let's see if I can do this" stage. I think mostly developers use info provided by FB for advertising purposes. That doesn't really interest me. So, other than that and what I've mentioned, I'm not sure what else I could do with the info from FB. I'm sure more research will be done.

On to the code:
I created two pages. The first page allows the visitor to sign into Facebook if they aren't already. Place the following attribute in the html tag. This allows your page to use the Facebook Markup Language (FBML).
xmlns:fb="http://www.facebook.com/2008/fbml"
Anywhere in the body, place this FBML tag. This displays the Facebook login/logout button. When logged in, FB stores a cookie for that user containing their UID and some other stuff.
<fb:login-button autologoutlink="true"></fb:login-button>
Finally for this page is the code that allows your page to use Facebook's JavaScript SDK. Place this code block right above the closing body tag. Replace 999999999999999 with your app id.
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({appId: '999999999999999', status: true, cookie: true,
xfbml: true});
};
(function() {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
</script>

The second page is where I retrieve the FB cookie and display some Facebook stuff. Again on this page, put the XFBML link in the HTML tag. First, I check for Facebook's cookie:
<cfif isDefined("cookie.FBS_999999999999999")>
Facebook encloses their cookie in quotes. So, with this code I remove the first and last quote:
<cfset fbc = #Right(cookie.fbs_999999999999999, len(cookie.fbs_999999999999999) - 1)#>
<cfset fbc = #Left(fbc, len(fbc) - 1)#>

The Facebook cookie contains several elements formed much like a querystring. I broke it up into an array like this:
<cfset myArrayList = ListToArray(fbc,"&")>
This next code block is the meat and potatoes. It creates the string to verify the link between your app and Facebook and stores the visitor's UID in its own cookie. Replace the 0's with your app secret.
<cfset strHash = "">
<cfloop array="#myArrayList#" index="ck">
<cfif findnocase("sig=", ck) eq 0>
<cfset strHash = "#strHash##ck#">
<cfif findnocase("expires=", ck) eq 0>
<cfset myArray = ListToArray(ck,"=")>
<cfcookie name="#myArray[1]#" value="#myArray[2]#">
</cfif>
<cfelse>
<cfset strSig = replacenocase(#ck#, "sig=", "")><br>
</cfif>
</cfloop>
<cfset strHash = "#strHash#00000000000000000000000000000000">

Essentially, what I'm doing in the above code is removing the sig value pair, creating a long string from the remaining pairs and also setting each of those pairs to it's own cookie. When the loop finds the sig pair, I record the value in a variable. At the end, I create the value to be hashed by appending my app secret to the end of the string I created in the loop (strHash, which isn't actually a hash yet).

With this conditional, I'm comparing the sig value to the hash of my long string I just created above.
<cfif #strSig# eq #Hash(strHash)#>
If that condition checks out, then you're golden. You can use http calls like the one below to request JSON responses from Facebook. This will get you basic information about "me", the current user.
<cfhttp url="https://graph.facebook.com/me?access_token=#cookie.access_token#" >

Here are the 2 pages in their entirety:
login.cfm:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>localhost:8500</title>
  </head>
  <body>
    <p><fb:login-button autologoutlink="true"></fb:login-button></p>


    <div id="fb-root"></div>
    <script>
      window.fbAsyncInit = function() {
        FB.init({appId: '999999999999999', status: true, cookie: true,
                 xfbml: true});
      };
      (function() {
        var e = document.createElement('script');
        e.type = 'text/javascript';
        e.src = document.location.protocol +
          '//connect.facebook.net/en_US/all.js';
        e.async = true;
        document.getElementById('fb-root').appendChild(e);
      }());
    </script>
  </body>
</html>


info.cfm

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:fb="http://www.facebook.com/2008/fbml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>localhost:8500</title>
  </head>
  <body>
<cfoutput>
<cfif isDefined("cookie.FBS_9999999999999999")>
<cfset fbc = #Right(cookie.fbs_99999999999999999, len(cookie.fbs_999999999999999) - 1)#>
<cfset fbc = #Left(fbc, len(fbc) - 1)#>

<cfset myArrayList = ListToArray(fbc,"&")>

<cfset strHash = "">
<cfloop array="#myArrayList#" index="ck">
<cfif findnocase("sig=", ck) eq 0>
 <cfset strHash = "#strHash##ck#">
 <cfif findnocase("expires=", ck) eq 0>
  <cfset myArray = ListToArray(ck,"=")>
  <cfcookie name="#myArray[1]#" value="#myArray[2]#">
 </cfif>
<cfelse>
 <cfset strSig = replacenocase(#ck#, "sig=", "")><br>
</cfif>
</cfloop>
<cfset strHash = "#strHash#00000000000000000000000000000000">

<cfif #strSig# eq #Hash(strHash)#>
#cookie.uid#<br>
</cfif>
</cfif><!---if isDefined(FBS_999999999999999)--->


<cfif isDefined("cookie.FBS_9999999999999999")>
<cfhttp url="https://graph.facebook.com/me?access_token=#cookie.access_token#" >
</cfhttp>
<cfimage action="writetobrowser" source="http://graph.facebook.com/#cookie.uid#/picture?type=large">
<cfset xd = "#DeserializeJSON(cfhttp.FileContent)#">
<cfdump var="#xd#"><br>

</cfif>
</cfoutput>
<br>

    <div id="fb-root"></div>
    <script>
      window.fbAsyncInit = function() {
        FB.init({appId: '999999999999999', status: true, cookie: true,
                 xfbml: true});
      };
      (function() {
        var e = document.createElement('script');
        e.type = 'text/javascript';
        e.src = document.location.protocol +
          '//connect.facebook.net/en_US/all.js';
        e.async = true;
        document.getElementById('fb-root').appendChild(e);
      }());
    </script>
  </body>
</html>

There are probably a dozen ways to make this code more efficient, but this will get you running. Visit Faccebook's docs to learn the many ways you can use this.

Monday, May 3, 2010

Unsuccessful istockphoto application #1

So I got this crazy idea to become an istockphoto.com contributor. It seemed like a no-brainer. Upload some photos, designers find them, download them and I collect the royalties. If nothing more I hope to get some free istock credits out of the deal. Well, it's more rigorous of an application than I thought.

My first image:
I thought this was a nice general stockable image. Invoking a mood and fairly conceptual. It has a lot of space at the top that could be used for copy, which is important for stock. Well, it was rejected.

My second image:
In hindsight, maybe not the best choice. However, I thought it was an interesting subject and hoped istock would bite. Nope

My third image:
My final sample image for my first application was that of a toy hula dancer. They mentioned that they needed pictures of figurines like this. Well, maybe not like this I guess. I suppose the hula dancer toy is very common and maybe I should've chosen a different background.

All 3 images got rejected. I wish they would've given a small critique for each, but no, just a general "At this time we regret to inform you that we did not feel the overall composition of your photography or subject matter is at the minimum level of standard for iStockphoto."
 
I had to wait 3 days before uploading new samples. I did and I'll share the results soon.

Friday, April 30, 2010

Unclear print featured in an Etsy treasury

My print titled "Unclear" found itself in an Etsy treasury.

Don't go too far...


My print was featured in a treasury on Etsy!