Exemplo n.º 1
0
    def parse(self, result: ParserResult, file_path: str) -> None:
        try:
            with open(file_path, "rt", encoding='utf-8') as f:
                parser = Parser()
                recipes = parser.parse_from_string(f.read())

        except Exception as e:
            raise MalformedDataError(
                "Cannot process BeerXML file because of {}".format(type(e)))

        if len(recipes) > 1:
            raise MalformedDataError(
                "Cannot process BeerXML file, because it contains more than one recipe"
            )
        beerxml = recipes[0]

        self.parse_recipe(result.recipe, beerxml)
        result.fermentables.extend(self.get_fermentables(beerxml))
        result.hops.extend(self.get_hops(beerxml))
        result.yeasts.extend(self.get_yeasts(beerxml))
Exemplo n.º 2
0
def test_node_to_object():
    "test XML node parsing to Python object"

    node = Element("hop")
    SubElement(node, "name").text = "Simcoe"
    SubElement(node, "alpha").text = 13
    SubElement(node, "amount").text = 0.5
    SubElement(node, "use").text = "boil"
    SubElement(node, "time").text = 30

    test_hop = Hop()

    recipe_parser = Parser()
    recipe_parser.nodes_to_object(node, test_hop)

    assert test_hop.name == "Simcoe"
    assert test_hop.alpha == 13
    assert test_hop.amount == 0.5
    assert test_hop.use == "boil"
    assert test_hop.time == 30
Exemplo n.º 3
0
def test_parse_recipe_2_from_string():

    xml_data = open(RECIPE_PATH_2, "r").read()
    recipe_parser = Parser()
    recipes = recipe_parser.parse_from_string(xml_data)
    assert_oatmeal_stout_recipe(recipes)
Exemplo n.º 4
0
def test_parse_recipe_2_from_file():

    recipe_parser = Parser()
    recipes = recipe_parser.parse(RECIPE_PATH_2)
    assert_oatmeal_stout_recipe(recipes)
Exemplo n.º 5
0
def test_parse_recipe_1_from_string():

    xml_data = open(RECIPE_PATH, "r").read()
    recipe_parser = Parser()
    recipes = recipe_parser.parse_from_string(xml_data)
    assert_simcoe_ipa_recipe(recipes)
Exemplo n.º 6
0
def test_parse_recipe_3_from_string():

    xml_data = open(RECIPE_PATH_3, "r").read()
    recipe_parser = Parser()
    recipes = recipe_parser.parse_from_string(xml_data)
    assert_coffee_stout_recipe(recipes)
Exemplo n.º 7
0
def test_parse_recipe_1_from_file():

    recipe_parser = Parser()
    recipes = recipe_parser.parse(RECIPE_PATH)
    assert_simcoe_ipa_recipe(recipes)
Exemplo n.º 8
0
def test_parse_recipe_3_from_file():

    recipe_parser = Parser()
    recipes = recipe_parser.parse(RECIPE_PATH_3)
    assert_coffee_stout_recipe(recipes)
Exemplo n.º 9
0
def beerxml_to_json(xml_file):
    """Convert beerxml recipe to JSON."""
    fermentable_type_map = {
        "grain": "GRAIN",
        "sugar": "SUGAR",
        "extract": "LIQUID EXTRACT",
        "dry extract": "DRY EXTRACT",
        "adjunct": "SUGAR",
    }

    yeast_type_map = {
        "ale": "ALE",
        "lager": "LAGER",
        "wheat": "WHEAT",
        "wine": "CHAMPAGNE",
        "champagne": "CHAMPAGNE",
    }


    yeast_form_map = {
        "liquid": "LIQUID",
        "dry": "DRY",
        "slant": "SLURRY",
        "culture": "CULTURE",
    }

    beers = []
    parser = Parser()
    # with open(xml_file, "rt") as file:
    tree = ElementTree.parse(xml_file)

    for recipe_node in tree.iter():
        if to_lower(recipe_node.tag) != "recipe":
            continue
        recipe = parser.parse_recipe(recipe_node)
        
        print("Working on", recipe.name)
        beer = {
            "fermentables": [],
            "hops": [],
            "yeasts": [],
            "extras": [],
            "mash_steps": [],
            "extra_info": {},
        }
        beer["boil_time"] = math.ceil(recipe.boil_time)
        beer["boil_loss"] = round(recipe.equipment.evap_rate, 2)
        beer["trub_loss"] = math.ceil(
            100 * (recipe.equipment.trub_chiller_loss / recipe.batch_size)
        )
        beer["dry_hopping_loss"] = 10
        beer["type"] = recipe.type.upper()
        beer["expected_beer_volume"] = f"{recipe.batch_size} l"
        # Mashing
        beer["mash_efficiency"] = recipe.efficiency
        beer["liquor_to_grist_ratio"] = 4
        for fermentable in recipe.fermentables:
            print(fermentable)
            beer["fermentables"].append(
                {
                    "type": fermentable_type_map[fermentable.type.lower()],
                    "name": fermentable.name.strip(".").strip(),
                    "amount": f"{fermentable.amount} kg",
                    "extraction": fermentable._yield,
                    "color": f"{fermentable.color} srm",
                    "use": "MASHING"
                    if getattr(fermentable, "is_mashed", "true").lower() == "true"
                    else "BOIL",
                }
            )
        for hop in recipe.hops:
            if hop.use.upper() == "DRY HOP":
                hoptime = math.ceil((hop.time / 60) / 24)
                time_unit = "DAY"
            else:
                hoptime = hop.time
                time_unit = "MINUTE"

            beer["hops"].append(
                {
                    "use": hop.use.upper(),
                    "name": hop.name.strip(".").strip(),
                    "amount": f"{hop.amount} kg",
                    "time": hoptime,
                    "time_unit": time_unit,
                    "alpha_acids": hop.alpha,
                }
            )
        for yeast in recipe.yeasts:
            beer["yeasts"].append(
                {
                    "name": yeast.name.strip(".").strip(),
                    "type": yeast_type_map[yeast.type.lower()],
                    "form": yeast_form_map[yeast.form.lower()],
                    "amount": f"{yeast.amount} kg",  # it could be liters but we keep only one
                    "lab": yeast.laboratory,
                }
            )
        for extra in recipe.miscs:
            beer["extras"].append(
                {
                    "type": extra.type.upper(),
                    "name": extra.name.strip(".").strip(),
                    "use": extra.use.upper(),
                    "amount": f"{extra.amount} kg",
                    "time": extra.time,
                    "time_unit": "MINUTE",
                }
            )
        for mash_step in recipe.mash.steps:
            beer["mash_steps"].append(
                {
                    "temperature": f"{mash_step.step_temp} c",
                    "time": mash_step.step_time,
                }
            )
        beer["name"] = recipe.name
        beer[
            "style"
        ] = f"{int(recipe.style.category_number)}{recipe.style.style_letter}"  # 2015 BJCP Category
        beers.append(beer)
    print(beers)
    return beers