...
Implementation
Our website is hosted on scripts.mit.edu. The two pages of the site (the front page and the search results page) are served as static HTML, CSS, and Javascript directly through Apache. We use FastCGI to provide a dynamic endpoint for fetching recipe results. This FastGCI script is written in Ruby. It uses Sinatra, a Ruby microframework for building web applications, as well as ActiveRecord, an object relational mapper. Our database is stored in MySQL, hosted by Amazon’s Relational Database Service. The schema of the database is illustrated below:
Our website uses Bootstrap as a CSS framework. The front page includes an autocomplete widget in the “Custom” form to complete the names of ingredients. Because we only have a couple thousand ingredients, it’s we can serve them all to the client, and search through them in javascript. Instead of creating a dynamic endpoint to generate this data on-the-fly, we created a script that generates a JSON file with all of the ingredients that we run any time we update the database. We then serve that JSON as a static file, loaded asynchronously once the rest of the home page is loaded. This minimizes server load (becuase the JSON doesn’t need to be generated for each client), and perceived latency (because the rest of the page loads before the JSON is requested). Finally, the homepage stores the user’s dietary restrictions is a in persistent cookie, saving user preferences automatically without the need for user accounts.
...
Our substitution data was generously provided by Chun-Yuen Teng, Yu-Ru Lin, and Lada A. Adamic, from the data use used for their paper, “Recipe recommendation using ingredient networks". To determine which ingredients violate which restrictions, we tagged each of our ingredients by hand, using an internal web-based tool we built (at http://vegitu.de/tagger, but it doesn’t list any ingredients anymore, as they’ve all been tagged). The recipes themselves are from http://www.nibbledish.com/, a website that hosts creative-commonsCreative Commons-licensed recipes. Using pythonPython, we wrote a crawler with Mechanize to find recipe pages, parsed the HTML with BeautifulSoup, and then used a number of heuristics to parse the ingredients list and populate our database with structured versions of the recipes.
...