I'm a bit of a pack-rat, at least when it comes to my email. Add to that my Type-A affinity for organization, and you find yourself square in the middle of Email Routing Rule Hell. When I first started adding rules to Outlook, I made the rookie mistake of creating 1 rule per sender; and I quickly wound up with hundreds of rules, which makes things unmanageable, and fast. I just wanted to post some tips here to hopefully help the pour lost souls out there that might be making the same mistakes I was. Do not give up! There is hope, friends!
Read more →
Posted in
Misc
| No Responses Yet
June 14 2010
I'm working on a webservice that has the potential to be quite dangerous. In the wrong hands, it could be used to spoof email, calendar, etc data from any person in our organization. So you can imagine that there is some concern about restricting access, even in development.
Since I'm working on my local machine, I simply need to limit access to this website in IIS to one specific IP address: localhost (127.0.0.1). In the days of IIS6, this was fairly easily done in the website properties dialog. On the directory security tab there were options to restrict to certain IP addresses or ranges.
These days, I'm on Windows 7, which comes with IIS7. And in IIS7, (of course!) this functionality has been buried. So I'm posting this both to help others, as well as to be a reminder for myself later down the road when I want to do this again.
The first thing you need to do is open up Control Panel > Programs and Features, and from there, choose Turn Windows Features on or off. Navigate to Internet Information Services > World Wide Web Services > Security and enable IP Security.

After you do this, you'll need to run iisreset before the change takes effect. If you have UAC enabled, be sure to run your command dialog as an administrator, otherwise you won't be able to run iisreset.
Lastly, to create the restrictions, open up the IIS Manager and select the website that you want to restrict. Open the IP Address and Domain Restrictions module, and then in the actions panel (on the right side) choose Edit Feature Settings…. To only allow local browsing, you should deny by default. Choose Deny from the dropdown, and hit OK. Then add your exceptions — the IP's or ranges that you want to allow access to. To do that, choose Add Allow Entry… from the action panel, and add all the exceptions you need.
These changes should take effect immediately.
Posted in
Misc
| No Responses Yet
May 14 2010
Pollyanna — or Secret Santa, as I understand it's often referred to outside of PA — is a great way to do a gift exchange in a large group while keeping costs down for those involved. Everyone is randomly assigned another member of the group to buy a gift for, and nobody knows who anyone else has been assigned. My wife and I do this with our friends, and to complicate things, most of us are married or at least dating, so we stipulate that you can't accept a drawing of your significant other. So when the hat gets passed to me, if I draw my wife's name, I just put it back and draw again. If we get stuck in a stalemate, we just start over.
We usually do our drawing during our Thanksgiving get-together, but this year we forgot. A quick Google search only showed one site that let you setup a Pollyanna, and it's got several requirements that don't meet my needs (#1 being that I don't want to make my friends sign up for a site just to do Pollyanna drawings); so I decided to write a quick ColdFusion script to do a random drawing that meets our extra rules and then automatically email everyone their gift recipient.
This is fairly basic, but it got the job done for us. If I were going to do anything else with it, I might add list support to the "noPick" option to allow listing multiple participants that can't be picked for the current person.
First, let's create a list of people who are participating, and their email addresses. In addition, put in each person's significant other in a field we'll call "noPick", so that we can stop them from picking that person.
<cfset variables.people = {
baz = {
email = "******@gmail.com",
noPick = ""
},
dave = {
email = "******@gmail.com",
noPick = ""
},
beth = {
email = "******@gmail.com",
noPick = "steve"
},
steve = {
email = "******@gmail.com",
noPick = "beth"
},
zach = {
email = "******@gmail.com",
noPick = "erin"
},
erin = {
email = "******@gmail.com",
noPick = "zach"
},
megan = {
email = "******@gmail.com",
noPick = "adam"
},
adam = {
email = "******@gmail.com",
noPick = "megan"
}
} />
Now, I know I'm going to want to randomly select from a list, so let's pull in listGetRandom from CFLib.
<cfscript>
/**
* Returns a random selection from a comma delimited list.
* Modified by Raymond Camden
*
* @param List The list to grab a random element from. (Required)
* @param Delimiter The list delimiter. Defaults to a comma. (Optional)
* @return Returns a random element from the list.
* @author Brad Breaux (bbreaux@blipz.com)
* @version 2, March 12, 2004
* http://cflib.org/udf/ListGetRandom
*/
function ListGetRandom(instring) {
var delim = ",";
var rnum = 0;
var r = '';
if(ArrayLen(Arguments) GTE 2) delim = Arguments[2];
if(listlen(instring) gt 0) {
rnum = randrange(1,listlen(instring,delim));
r = listgetat(instring,rnum,delim);
}
return r;
}
</cfscript>
Now, I know from first-hand experience that this can sometimes result in two or three complete restarts due to deadlock. When you're dealing with true randomness, there's no telling how many restarts you might need, so I know I want to write a recursive function so that it can restart itself as many times as needed if we detect a deadlock; and I want it to accept my original structure of people as input.
Inside that function, let's immediately create 2 lists of all of the participants: 1 to loop over for the person drawing from the hat, and 1 to represent the names in the hat. We'll also need a structure to hold all of the successful drawings, a variable to hold the current pick from the hat, and a variable to act as our loop index.
<cffunction name="getRandomPicks">
<cfargument name="people" type="Struct" />
<cfset var allPeople = lcase(structKeyList(arguments.people)) />
<cfset var remainingPeople = "#allPeople#" />
<cfset var picks = {} />
<cfset var thisPick = '' />
<cfset var thisPerson = '' />
Loop over all of our entrants – once each – and let them pick a name randomly from the pool of remaining names in the hat.
<cfloop list="#allPeople#" index="thisPerson">
<!--- pick a random person --->
<cfset thisPick = listGetRandom(remainingPeople) />
This is where we start to apply our constraints. Deadlock is when there's only one name left in the hat, and it's either the person themself, or their significant other. Check for deadlock, and if it's found, recurse.
<!--- detect deadlocks and start over when necessary --->
<cfif listLen(remainingPeople) eq 1>
<cfif remainingPeople eq arguments.people[thisPerson].nopick>
<cfreturn getRandomPicks(arguments.people) />
<cfelseif thisPerson eq thisPick>
<cfreturn getRandomPicks(arguments.people) />
</cfif>
</cfif>
There's actually one more deadlock scenario that I didn't run into in my testing or pick up on until I started writing this all out. Do you see it? (Answer is in the next paragraph, so don't jump ahead if you want to figure it out.)
It's when there are 2 names left in the hat and they are myself and my significant other. So, to account for that, let's rewrite the above code as follows. We'll loop over the remaining names in the hat, and the first time we find a name that doesn't violate the rules, we break out of the loop. If we make it all the way through the loop, we're in a deadlock, and need to restart.
<!--- if only person left to pick is the no-pick for this person, and/or themself, start over --->
<cfif listLen(remainingPeople) lte 2>
<cfset deadlock = true />
<cfloop list="#remainingPeople#" index="dlTest">
<cfif dlTest neq thisPerson and dlTest neq arguments.people[thisPerson].noPick>
<cfset deadlock = false />
<cfbreak />
</cfif>
</cfloop>
<cfif deadlock>
<cfreturn getRandomPicks(arguments.people) />
</cfif>
</cfif>
Since we're adding two new variables for the deadlock check, don't forget to go back and var scope them.
So now we know we're not in a deadlock, the only remaining rule is that as long as I've picked myself or my significant other, I need to put that name back and draw another one. Once I've drawn a suitable name, escape this loop.
<!--- we know there's more than 1 person left to pick, so pick randomly until we get a good one --->
<cfloop condition="true eq true">
<cfif thisPick eq arguments.people[thisPerson].nopick>
<cfset thisPick = listGetRandom(remainingPeople) />
<cfelseif thisPick eq thisPerson>
<cfset thisPick = listGetRandom(remainingPeople) />
<cfelse>
<cfbreak />
</cfif>
</cfloop>
Remove the selection from the pool of remaining people, save the selection so that it can be used later to send an email, and pass the hat.
<!--- pick is good, so remove pick from remaining people --->
<cfset remainingPeople = listDeleteAt(remainingPeople,listFindNoCase(remainingPeople,thisPick)) />
<!--- save the pick --->
<cfset picks[thisPerson] = thisPick />
</cfloop>
<cfreturn picks />
</cffunction>
That's the meat and potatoes of the selection. All that's left is to send the emails, and I'm sure you can figure out how to do that.
Posted in
ColdFusion |
Misc
| 1 Response
November 16 2009
This blog, before I bought the domain FusionGrokker.com, lived at http://tuttletree.com/NerdFusion/ — a subfolder of my family blog. While there and operating under the title "NerdFusion," I setup FeedBurner using the same title, NerdFusion. When I bought this domain and moved my blog here, I knew I would rather have my FeedBurner URL reflect my new blog title; but I also knew from past experience that changing the FB url causes problems. Doing so abandons any and all subscribers, and after you realize that, you can't get the old url back, because it's "in use" (by whom, exactly?!) So I just left well enough alone, and until today I have been continuing to point my RSS links to the old FeedBurner link.
In my mind, this is retarded because the whole point of using FeedBurner in the first place is so that you can change your blog domain or blogging platform without losing subscribers in the process. If they have the same problem — albeit, not exactly the same, but close enough — then what benefit are they really providing? Ideally, they would allow you to create an alias that points back to the original feedburner url, as long as it was unique and available. Heaven forbid the easy, correct method be available though, right? This started as an informational post and has derailed into a rant.
*Cough* Back to business.
So FeedBurner has some, erm, "problems." I would really recommend that you not change your FB url.
Instead, create a new one and have your subscription links point to it. Let your old readers continue to use the old FB url. It won't hurt anything, I promise. The only down-side I've found to this, so far, is that your stats are now split between the two. I'm not much of a stats whore any more though, so it doesn't bother me that much — which is to say, at all. Half the time I can't remember my FeedBurner password, let alone feel like checking my RSS stats.
Now, my RSS link is what it should be: http://feeds2.feedburner.com/FusionGrokker/
I hope this helps prevent people from making the mistake of changing their FeedBurner URL only to find they have kicked their subscribers to the curb.
Posted in
Misc
| 4 Responses
March 06 2009