Переглянути джерело

Working on getting recipes details (LitK)

Tati 7 роки тому
батько
коміт
dd912a6796

+ 2 - 2
ktchn/package.json

@@ -4,7 +4,7 @@
   "private": true,
   "scripts": {
     "start": "ts-node --inspect-brk=9229 src/server.ts",
-    "dev": "nodemon",
+    "dev": "node node_modules/nodemon/bin/nodemon.js ts-node --inspect-brk=9229 src/server.ts",
     "build": "tsc -p .",
     "build:live": "nodemon --watch 'src/**/*.ts' --exec ts-node src/server.ts"
   },
@@ -29,7 +29,7 @@
     "eslint": "^5.8.0",
     "eslint-config-airbnb-base": "^13.1.0",
     "eslint-plugin-import": "^2.14.0",
-    "nodemon": "^1.18.5",
+    "nodemon": "^1.18.9",
     "ts-node": "^7.0.1",
     "typescript": "^3.1.3"
   }

+ 29 - 17
ktchn/src/recipes/index.ts

@@ -1,32 +1,44 @@
 interface QtyMetric {
-  qty: Number;
-  unit: String;
+  qty: number;
+  unit: string;
 }
 
 interface Ingredient {
-  name: String;
+  name: string;
   qtyMetric: QtyMetric;
-  qtyCups: Number;
-  note: String;
+  qtyCups: number;
+  note: string;
 }
 
 interface Temperature {
-  celsius: Number;
-  farenheid: Number;
+  celsius: number;
+  farenheid: number;
 }
 
-class Recipe {
-  public name: String;
-  tags!: String[];
+export class RecipeDetails {
+  [key:string]: number
+  preparationTime: number;
+  cookingTime: number;
+  servings: number;
+
+  constructor(
+    prepTime:number|string = 0,
+    cookingTime:number|string = 0,
+    servings:number|string = 0) {
+      this.preparationTime = Number(prepTime);
+      this.cookingTime = Number(cookingTime);
+      this.servings = Number(servings);
+    }
+}
+
+export class Recipe {
+  public name: string;
+  tags!: string[];
   ingredients!: Ingredient[];
-  servings!: Number;
-  cookTime!: Number;
-  preparationTime!: Number;
-  directions!: String[];
+  details: RecipeDetails = new RecipeDetails();
+  directions!: string[];
 
   constructor(name:string) {
     this.name = name;
   }
-}
-
-export default Recipe;
+}

+ 2 - 4
ktchn/src/recipes/routes.ts

@@ -17,10 +17,8 @@ class RecipeRoutes {
     this.router.post("/scrape", (req, res, next) => {
        console.log("body", req.body);
        return Scrape(req.body.url).then((x)=>{
-         console.log('x', x);
-         res.json({
-           message: 'thx'
-         })
+         console.log('xjj', x);
+         res.json(x)
        });
     })
   }

+ 49 - 5
ktchn/src/recipes/scrape.ts

@@ -1,30 +1,72 @@
 import RequestPromise from "request-promise";
 import Cheerio from "cheerio";
-import Recipe from "./index";
+import { Recipe, RecipeDetails } from './index';
 import { json } from "body-parser";
 import { stringify } from "querystring";
 import { UriOptions } from "request";
+import { any } from "bluebird";
+
+const LAURA_MAP = {
+  'Preparation': {
+    key: 'preparationTime',
+    transform: (data: string) => {
+      let getHoursAsMin = (data: string) => {
+        let result = data.match(/(\d+) hours?/);
+        return result ? (parseInt(result[0])*60) : 0;
+      };
+      let getMinutes = (data: string) => {
+        let result = data.match(/(\d+) minutes?/);
+        return result ? parseInt(result[0]) : 0;
+      };
+      return getHoursAsMin(data) + getMinutes(data);
+    },
+  },
+  'Cook time': {
+    key: 'cookTime',
+    transform: (data: string) => data,
+  },
+  'Servings': {
+    key: 'servings',
+    transform: (data: string) => data,
+  }
+};
 
 function getIngredients($:CheerioSelector): Recipe {
   let r = new Recipe('');
   const ingredientsScrape = $('.cs-ingredients-check-list > ul').children();
-  console.log(ingredientsScrape.length);
+  //console.log(ingredientsScrape.length);
 
   return r;
 }
 
+function getRecipeDetails($:CheerioSelector):RecipeDetails {
+  let details = new RecipeDetails();
+  const detailsMap = Object.keys(details);
+  const data = $('.cs-recipe-details').find('div');
+  let x: any = {};
+  data.each((i, el) => {
+    let key: string = $(el).find('span').text();
+    x[key] = $(el).contents().last().text();
+  });
+  console.log(LAURA_MAP.Preparation.transform(x.Preparation));
+  
+  return details;
+}
+
 function lauraInTheKitchen($:CheerioSelector):Recipe {
   let recipe = new Recipe($('.cs-page-title>h1').text().trim());
   const recipeDetails = $('.cs-recipe-details').find('div');
   
   const recipeMap = ['preparationTime', 'cookTime', 'servings'];
+  getRecipeDetails($);
   recipeDetails.each((i:any, el:any) => {
-    if (i > 2) return false;
+    if (i > (recipeMap.length-1)) return false;
     var x = $(el).contents().toArray();
+    //console.log($(x).text());
     recipe = {
       ...recipe,
       [recipeMap[i]]: $(x).not('span').text().replace(/\D/g,''),
-    } 
+    };
   })
   
   getIngredients($);
@@ -34,7 +76,9 @@ function lauraInTheKitchen($:CheerioSelector):Recipe {
 function scrape(url:string) {
   const options = {
     uri: url,
-    transform: (body: any) => Cheerio.load(body),
+    transform: (body: any) => Cheerio.load(body, {
+      normalizeWhitespace: true
+    }),
   };
   return RequestPromise(options).then(($) => {
     return lauraInTheKitchen($);

+ 1 - 1
ktchn/src/server.ts

@@ -18,8 +18,8 @@ class App {
   }
 
   private routes(): void {
-    this.express.use("/", rootRouter);
     this.express.use("/recipes", recipeRouter);
+    this.express.use("/", rootRouter);
   }
 
   private middleware(): void {