118 lines
3.3 KiB
Python
Executable File
118 lines
3.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Main entry point for the Nutritional Recipe Parser application.
|
|
|
|
Supports both CLI and GUI modes.
|
|
"""
|
|
|
|
from nutri_parser import Recipe, RecipeParser, NutritionApi
|
|
import argparse
|
|
import sys
|
|
import os
|
|
|
|
|
|
def main_gui():
|
|
"""Launch the tkinter GUI application."""
|
|
try:
|
|
import tkinter as tk
|
|
from nutri_parser import NutritionApi
|
|
root = tk.Tk()
|
|
app = RecipeAppGUI(root)
|
|
root.mainloop()
|
|
except ImportError:
|
|
print("Tkinter not available. Using CLI mode instead.")
|
|
main_cli()
|
|
|
|
|
|
def main_cli() -> None:
|
|
"""Command-line interface entry point."""
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description="Parse nutritional values from recipe files.",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog="""
|
|
Examples:
|
|
%(prog)s recipe.md
|
|
%(prog)s --output-json recipe.md output.json
|
|
%(prog)s --list-foods
|
|
%(prog)s --verbose recipe.md
|
|
""",
|
|
)
|
|
parser.add_argument("input_file", nargs="?", help="Input recipe file")
|
|
parser.add_argument("--output-json", "-o", help="Output JSON file path")
|
|
parser.add_argument("--list-foods", "-l", action="store_true",
|
|
help="List cached ingredients")
|
|
parser.add_argument("--verbose", "-v", action="store_true",
|
|
help="Verbose output")
|
|
|
|
args = parser.parse_args()
|
|
|
|
api = NutritionApi()
|
|
|
|
if args.list_foods:
|
|
# Show what we have in cache
|
|
cursor = api.conn.execute("SELECT ingredient_name FROM ingredient_cache")
|
|
rows = cursor.fetchall()
|
|
if rows:
|
|
print("Cached ingredients ({}):".format(len(rows)))
|
|
for row in rows:
|
|
print(f" {row[0]}")
|
|
else:
|
|
print("No cached ingredients yet. Parse a recipe to populate the cache.")
|
|
return
|
|
|
|
if not args.input_file:
|
|
parser.print_usage()
|
|
sys.exit(1)
|
|
|
|
if not os.path.exists(args.input_file):
|
|
print(f"Error: File not found: {args.input_file}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
with open(args.input_file, "r", encoding="utf-8") as f:
|
|
text = f.read()
|
|
|
|
cli_parser = RecipeParser()
|
|
try:
|
|
parsed = cli_parser.parse(text)
|
|
except Exception as e:
|
|
print(f"Error parsing recipe: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
try:
|
|
recipe = Recipe(parsed, api=api, servings=parsed.servings)
|
|
except Exception as e:
|
|
print(f"Error looking up nutrition: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
if args.verbose:
|
|
print(recipe.summary())
|
|
|
|
# Print JSON to stderr (so stdout can be used separately) or stdout
|
|
json_output = recipe.to_json()
|
|
if args.output_json:
|
|
with open(args.output_json, "w", encoding="utf-8") as f:
|
|
f.write(json_output)
|
|
print(f"Exported to: {args.output_json}", file=sys.stderr)
|
|
else:
|
|
# Print a human-readable summary to stdout
|
|
print(recipe.summary(), file=sys.stdout)
|
|
# Also print JSON to stderr for pip/redirect use
|
|
print("\n--- JSON ---", file=sys.stderr)
|
|
print(json_output, file=sys.stderr)
|
|
|
|
|
|
def main() -> None:
|
|
"""Determine mode: GUI if no args, otherwise CLI."""
|
|
import sys
|
|
|
|
# If no arguments at all, launch GUI
|
|
if len(sys.argv) == 1:
|
|
main_gui()
|
|
else:
|
|
main_cli()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|