Skip to content

Instantly share code, notes, and snippets.

@s1037989
Last active January 24, 2016 18:41
Show Gist options
  • Save s1037989/65361c9af53110b28b7b to your computer and use it in GitHub Desktop.
Save s1037989/65361c9af53110b28b7b to your computer and use it in GitHub Desktop.
Code and demo of MyZoutritionPal
$ cat myapp.pl 
#!/usr/bin/env perl
use Mojolicious::Lite;

my $nn = Mojo::UserAgent->new;
$nn->get('http://zoutrition.missouri.edu/zoutrition');

get '/ShowItemNutritionLabel/:unitOid/:menuOid/:detailOid' => sub {
  my $c = shift;
  $c->render_later;
  my $headers = {
    'X-Requested-With' => 'XMLHttpRequest',
  };
  my $form = {
    unitOid => $c->param("unitOid"),
    menuOid => $c->param("menuOid"),
    detailOid => $c->param("detailOid"),
  };
  $nn->post("http://zoutrition.missouri.edu/zoutrition/NutritionDetail/ShowItemNutritionLabel" => $headers => form => $form => sub {
    my ($ua, $tx) = @_;
    $c->render(text => $tx->res->body);
  });
};

app->start;

Notice how I'm requesting nutrition information for Thin Crust Cheese Pizza, on Monday, from Plaza 900 (unitOid, menuOid, detailOid)

$ perl myapp.pl get /ShowItemNutritionLabel/22/1081022/102606301
[Sun Jan 24 12:34:08 2016] [debug] GET "/ShowItemNutritionLabel/22/1081022/102606301"
[Sun Jan 24 12:34:08 2016] [debug] Routing to a callback
[Sun Jan 24 12:34:09 2016] [debug] 200 OK (0.459254s, 2.177/s)

<div id="nutritionLabel" class="cbo_nn_NutritionLabelDiv">
<table class='cbo_nn_NutritionLabelTable' cellpadding='0' cellspacing='0' style='width:100%;'><tr><td><table width='100%'><tr><td class='cbo_nn_LabelHeader'>THIN CRUST CHEESE PIZZA</td><td style='text-align:right;'><button id='close' name='close' type='button' class='cbo_nn_closeButton'  onclick="javascript:closeNutritionDetailPanel();" title='Close this panel'><img src='images/buttons/close.png' alt='Close'/></button></td></tr></table></td></tr><tr><td class='cbo_nn_LargeLabelHeader'>Nutrition Information</td></tr><tr><td class='cbo_nn_LabelBottomBorderLabel'>Serving Size:&nbsp;1/10TH PIZZA&nbsp;(71g)</td></tr><tr><td class='cbo_nn_LabelAmountServed'>Amount Per Serving</td></tr><tr><td class='cbo_nn_LabelBorderedSubHeader' style='white-space:nowrap;'><table style='width:100%;' cellpadding='0' cellspacing='0'><tr><td class='cbo_nn_LabelDetail'><font style='font-weight: bold;'>Calories:</font>&nbsp;&nbsp;<span class='cbo_nn_SecondaryNutrient'>165</span></td><td class='cbo_nn_SecondaryNutrient'>Calories from Fat:&nbsp;&nbsp;<span class='cbo_nn_SecondaryNutrient'>72</span></td></tr></table></td></tr><tr><td align='right' class='cbo_nn_LabelDailyValue'>% Daily Value</td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td colspan='2' class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:bold;'>Total Fat:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;8&nbsp;Gram</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>12%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td width='10px'>&nbsp;</td><td class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:normal;'>Saturated Fat:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;4&nbsp;Gram</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>22%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td width='10px'>&nbsp;</td><td class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:normal;'>Trans Fat:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;0&nbsp;Gram</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td colspan='2' class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:bold;'>Cholesterol:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;15&nbsp;MG</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>7%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td colspan='2' class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:bold;'>Sodium:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;310&nbsp;MG</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>17%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td colspan='2' class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:bold;'>Total Carbohydrate:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;16&nbsp;Gram</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>6%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td width='10px'>&nbsp;</td><td class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:normal;'>Dietary Fiber:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;1&nbsp;Gram</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>3%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td width='10px'>&nbsp;</td><td class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:normal;'>Sugars:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;1&nbsp;Gram</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>%</td></tr></table></td></tr></table></td></tr><tr><td><table width='100%' cellpadding='0' cellspacing='0'><tr><td colspan='2' class='cbo_nn_LabelBorderedSubHeader'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td style='width:70%; padding-left: 20px'><table cellpadding='0' cellspacing='0' style='width:100%;'><tr><td class='cbo_nn_LabelDetail' style='width:*'><font style='font-weight:bold;'>Protein:</font></td><td><font class='cbo_nn_SecondaryNutrient'>&nbsp;9&nbsp;Gram</font></td></tr></table></td><td style='width:30%;' align='right' class='cbo_nn_LabelLeftPaddedDetail'>10%</td></tr></table></td></tr></table></td></tr><tr><td><table style='width:100%;' cellpadding='0' cellspacing='0' class='cbo_nn_LabelSecondaryTable'><tr><td class='cbo_nn_SecondaryNutrientLabel'>Vitamin A:<span class='cbo_nn_SecondaryNutrient'>&nbsp;10%</span></td><td class='cbo_nn_SecondaryNutrientSpacer'><img src='images/bullet_gray.gif' alt=''/></td><td class='cbo_nn_SecondaryNutrientLabel'>Vitamin C:<span class='cbo_nn_SecondaryNutrient'>&nbsp;0%</span></td></tr><tr><td class='cbo_nn_SecondaryNutrientLabel'>Calcium:<span class='cbo_nn_SecondaryNutrient'>&nbsp;8%</span></td><td class='cbo_nn_SecondaryNutrientSpacer'><img src='images/bullet_gray.gif' alt=''/></td><td class='cbo_nn_SecondaryNutrientLabel'>Iron:<span class='cbo_nn_SecondaryNutrient'>&nbsp;0%</span></td></tr></table></td></tr><tr><td><table cellpadding='0' cellspacing='0'><tr><td><span class='cbo_nn_LabelIngredientsBold'>Ingredients:</span><span class='cbo_nn_LabelIngredients'>16" THIN PARBAKED PIZZA CRUST(INGREDIENTS: FLOUR (WHEAT, MALTED BARLEY), WATER, SOYBEAN OIL, YEAST, SALT, DEXTROSE, CALCIUM PROPIONATE (PRESERVATIVE), AND SOY LECITHIN),&nbsp;AUTHENTIC TOMATO PIZZA SAUCE(VINE-RIPENED FRESH TOMATOES, BLEND OF EXTRA VIRGIN OLIVE OIL AND SUNFLOWER OIL, SALT, OREGANO, GRANULATED GARLIC, BLACK PEPPER AND NATURALLY DERIVED CITRIC ACID.),&nbsp;PIZZA CHEESE(PART SKIM MOZZARELLA (PASTEURIZED PART SKIM MILK, CHEESE CULTURES, SALT, ENZYMES), UNSMOKED PROVOLONE (PASTEURIZED MILK, CHEESE CULTURES, SALT, ENZYMES), POWDERED CELLULOSE TO PREVENT CAKING, GRATED ROMANO MADE FROM COW'S MILK (PASTEURIZED PART SKIM MILK, CHEESE CULTURES, SALT, ENZYMES), GRATED PARMESAN (PASTEURIZED PART SKIM MILK, CHEESE CULTURES, SALT, ENZYMES).),&nbsp;MONTERY JACK SHREDDED CHEESE(PASTEURIZED MILK, CHEESE CULTURE, SALT, ENZYMES, POTATO STARCH, CORN STARCH, POWDERED CELLULOSE ADDED TO PREVENT CAKING, NATAMYCIN (A NATURAL MOLD INHIBITOR).),&nbsp;FRESH SHREDDED PARMESAN CHEESE(PARMESAN CHEESE (PASTEURIZED PART SKIM MILK, CHEESE CULTURES, SALT, ENZYMES), POWDERED CELLULOSE TO PREVENT CAKING, NATAMYCIN TO PROTECT FLAVOR OR PART SKIM MILK, CHEESE CULTURE, SALT, ENZYMES, POTATO STARCH AND POWDERED CELLULOSE ADDED TO PREVENT CAKING, NATAMYCIN (NATURAL MOLD INHIBITOR) (AGED OVER 10 MONTHS) OR PASTEURIZED PART SKIM MILK, CHEESE CULTURE, SALT, ENZYMES, CORN FLOUR CELLULOSE ADDED TO PREVENT CAKING.)</span></td></tr></table></td></tr><tr><td><table cellpadding='0' cellspacing='0'><tr><td><span class='cbo_nn_LabelAllergensBold'>Contains:</span><span class='cbo_nn_LabelAllergens'>Alcohol,&nbsp;Corn,&nbsp;Garlic,&nbsp;Gluten,&nbsp;Milk,&nbsp;Soy,&nbsp;Wheat</span></td></tr></table></td></tr></table>
</div>

We would need to talk all of ZouTrition to get all unit, menu, and detailOids. But at least then we'd have it all. But then the next problem is that all nutrition information is HTML formatted and not raw data (JSON). We could potentially parse the HTML, but HTML is notorious for its inconsistency.

It would definitely be ideal to get the raw data from Mizzou and convert that data to a format that MyFitnessPal would accept. I don't know if there's a bulk upload feature, or if we'd have to programmatically submit one entry at a time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment