Josh Ourisman » On the other hand

Navigation: Blog, Portfolio

Boston Restaurant Week, Winter 2009

February 18th, 2009

I can't believe I haven't written about this yet, but BostonChefs.com's the unofficial guide to Boston's Restaurant Week for Winter 2009 is live. I've been working on this particular site since 2007 when I first help make some PHP-based improvements to it. Last summer it became my first professional Django-based project when I completely redeveloped it in Django. This year I've made some further improvements to the Django codebase, including a completely re-implemented and much improved Google Maps mashup that lets you view the restaurants geographically.

Previously this had been using some old code that I had inherited from the original site. It was pretty good code, but more modern tools allowed me to vastly simplify it. Specifically, instead of always loading every restaurant and populating the map with markers, then simply zooming in on a specific neighborhood or restaurant, it now only loads the restaurants appropriate for the current target. If you select a specific neighborhood, it only loads the restaurants for that neighborhood, and puts markers on the map for them. Because of that I was able to use Google's API to automatically set the bounds and zoom level of the map to best show those restaurants. This removes the need to manually pick a set of coordinates and zoom level for each neighborhood (having, then, to fine tune it for each neighborhood individually) and instead takes care of all that automatically. The result is a map that's simpler to manage, presents the relevant information more intelligently, and is much quicker to load. All in all, I think it's a pretty big improvement.

BostonChefs 2.0 is live!

January 14th, 2009

This post is actually a few weeks overdue, but we were away on vacation for a couple weeks, and I'm still in the process of catching up from everything. Anyway, the new BostonChefs.com is live! There haven't been any major changes since the public beta I announced a few months ago, but there have been a few minor tweaks and even a couple new features added. This is my first major Django project to go live, and while there's still some work to be done it's nice to see the product of so much work finally going out the door.

But there's no rest for the weary, and I've got a fairly large number of more projects in the pipeline including at least three more Django projects of varying sizes, and one in CodeIgniter. The next few months, if not the whole of 2009, promise to be quite busy!

Hours of Operation

December 16th, 2008

As you probably know, I've been working on a Django-based re-build of BostonChefs.com (the new version of which is actually live now, but due to DNS propagation issues isn't yet available to 100% of people which is why I haven't yet written a post about it). Among other things, BostonChefs.com provides information on some of the fantastic restaurants in the Boston area. One piece of information it provides is the hours of operation of those restaurants. In order to store this information I created a model called HoursOfOperation. It looks like this:

class HoursOfOperation(models.Model):
DAY_CHOICES = (
('0', 'Sun'),
('1', 'Mon'),
('2', 'Tue'),
('3', 'Wed'),
('4', 'Thur'),
('5', 'Fri'),
('6', 'Sat'),
)
restaurant = models.ForeignKey("Restaurant")
meal_period = models.ForeignKey("MealPeriod")
day = models.CharField(max_length=3, choices=DAY_CHOICES)
open_time = models.TimeField(default=datetime.datetime.now)
close_time = models.TimeField(default=datetime.datetime.now)

def _get_hours(self):
return "%s - %s" % (self.open_time.strftime('%I:%M%p'), self.close_time.strftime('%I:%M %p'))
hours = property(_get_hours)

As you can see, each 'hour' is related to a restaurant and a meal period, which allows us to display the information in a manner similar to that you might find on a store's front sign. For example, if you go to the Grill 23 & Bar page (my personal favorite restaurant in Boston, although Craigie on Main is a decent challenger), you'll see something like this:

DINNER
* Sun: 5:30 p.m.-10 p.m.
* Mon-Thur: 5:30 p.m.-10:30 p.m.
* Fri: 5:30 p.m.-11 p.m.
* Sat: 5 p.m.-11 p.m.

Building a list like that out of the above model proved slightly more difficult that I might have hoped. It required quite a lot of template logic, including writing a custom filter. The block of template code necessary to generate that list looks like this:

<div class="hours">
{% regroup restaurant.hoursofoperation_set.all by meal_period as periods %}
{% for period in periods %}
<div class="hoursMealPeriod">{{ period.grouper }}</div>
{% regroup period.list by hours as hour_list %}
<ul>
{% for hour in hour_list %}
<li>{{ hour.list|collapsedays }}</li>
{% endfor %}
</ul>
{% endfor %}
</div>

As you can see, somewhat complex. Those nested {% regroup %}s can be nasty to wrap your head around, if nothing else. But basically it's taking the set of HoursOfOperation objects related to the restaurant, grouping them by meal period, then taking the subset of those objects for each meal period, and grouping those by the hours of the day they represent. So what you're then left with is a list of all the different time periods (still represented as HoursOfOperation objects) that the restaurant is open for a given meal period, and the days on which it is open during those hours. As you can see above, the days are represented by number of the day of the week (0 for Sunday through 6 for Saturday).

Converting that list integers into something like 'Mon, Wed-Fri' was not very easy, and certainly not something I wanted to try to tackle using Django's template tags. I ended up drawing heavily on my hazy memories of CS 127 (many thanks to Dave who taught me all about recursion way back then) and creating a filter that considers the list of HoursOfOperation objects as a list of those integers, then recursively converts it into a list of lists representing the subsets of contiguous days in the list. So if you start out with [1, 3, 4, 5] you end up with [[1, 1], [3, 5]] which is then converted into 'Mon, Wed-Fri'. After several false starts I ended up with this beauty of a Django template filter:

from django.template import Library
from django.template.defaultfilters import time

from types import ListType

register = Library()

def simplify(index, found, days):
high = index+1
mid = index
low = index-1
if not found:
days[low] = [days[low], days[low]]
if high >= len(days):
if not isinstance(days[-1], ListType):
if days[-1] == days[-2][1]:
days.pop(-1)
else:
days[-1] = [days[-1], days[-1]]
return days
if int(days[high].day) - int(days[mid].day) == 1 and (found or int(days[mid].day) - int(days[low][0].day) == 1):
days[low][1] = days[high]
days.pop(mid)
high = high-1
found = True
else:
if found:
days.pop(mid)
found = False
return simplify(high, found, days)

@register.filter
def collapsedays(value):
hours = "%s-%s" % (time(value[0].open_time), time(value[0].close_time))
days = simplify(1, False, value)
for i in range(len(days)):
if days[i][0] == days[i][1]:
days[i] = days[i][0].get_day_display()
else:
days[i] = "%s-%s" % (days[i][0].get_day_display(),
days[i][1].get_day_display())
return "%s: %s" % (', '.join(days), hours)


Fresh from the Family Farm: A new project goes live

September 12th, 2008

It's always fun doing this: a new project has gone live! In cooperation with BostonChefs.com, Fresh from the Family Farm is an event for local Boston-area restaurants to showcase the possibilities of local ingredients from area family farms. The event runs from Oct. 12 through Oct. 19, and a list of participating restaurants, along with links to make reservations through OpenTable (where available), and links to the restaurant's BostonChefs.com profile (also where available).

The website is powered by Django (which is now at 1.0, something I plan to write about soon), which even still I am growing to love more and more as I use it.

Boston Restaurant Week

July 16th, 2008

As those in the Boston area are probably aware, this years Summer Restaurant Week is fast approaching. This year it will be two weeks, those of August 10 through August 15 and August 17 though August 22. If you've been reading my blog for a while you may know that one year ago, almost to the day (off by 5) I announced that I had helped work on BostonChefs.com's Unofficial Guide to Restaurant Week. Well, this year I'm announcing the same thing.

The site just went live with all the information you might want about what's going on with this Summer's Restaurant Week including the restaurants that are participating, what meals they'll be serving, what's on their menus (where available), and a Google Maps mashup to help you find them. The site has been completely redeveloped and is now powered by Django, making this my first Django-based project to go live! (Not counting my own website, of course.)

Go check it out, and bon appetit!

Boston's Restaurant Week

July 11th, 2007

Most of you probably know about Boston's Restaurant Week. For those that don't, it's a week (or more) that happens twice a year during which participating Boston area restaurants offer meals from a prix fixe menu at very low prices. For example, Excelsior will be offering a three-course meal for $33.07 (I might just have to give that a try).

What you probably didn't know is that there's a fantastic website at restaurantweekboston.com (offered by bostonchefs.com) that will show you all the participating restaurants, the details of their participation, the prix fixe menus that they are offering, and a Google maps mashup to help you locate and get to those restaurants.

I helped create it, so you should go use it to help justify my services. ;)


copyright © Joshua Ourisman 2006-2010 all rights reserved