#!/usr/bin/perl use warnings; use strict; use DBI; use DateTime; use DateTime::Format::ISO8601; my $db = DBI->connect("dbi:SQLite:recipe.db", "", "", {RaiseError => 1, AutoCommit => 1}); my @recipes; my @ingredients; my @contents; sub read_recipe_db { # All recipes needs to be read to be able to pick random recipes easily # enough. my $all = $db->selectall_arrayref("SELECT * FROM recipes"); foreach my $row (@$all) { my ($id) = @$row; $recipes[$id]->{'name'} = @$row[1]; $recipes[$id]->{'uri'} = @$row[2]; } # This is not how to do the ingredient and content reading! # They should only be read for relevant recipes. $all = $db->selectall_arrayref("SELECT * FROM ingredients"); foreach my $row (@$all) { my ($id) = @$row; $ingredients[$id]->{'id'} = @$row[1]; $ingredients[$id]->{'name'} = @$row[2]; } $all = $db->selectall_arrayref("SELECT * FROM contents"); foreach my $row (@$all) { my ($id) = @$row; $contents[$id]->{'recipe_id'} = @$row[1]; $contents[$id]->{'ingredient_id'} = @$row[2]; $contents[$id]->{'quantity'} = @$row[2]; $contents[$id]->{'unit'} = @$row[2]; } } sub get_random_recipe { return int(rand(@recipes)); } sub get_recipe_name ($) { my ( $id ) = @_; if ($recipes[$id]->{'name'}) { return $recipes[$id]->{'name'}; } else { return "NULL"; } } sub get_recipe_uri ($) { my ( $id ) = @_; if ($recipes[$id]->{'uri'}) { return $recipes[$id]->{'uri'}; } else { return "NULL"; } } my @schedule = ( { day => "Måndag", }, { day => "Tisdag", }, { day => "Onsdag", }, { day => "Torsdag", }, { day => "Fredag", } ); sub cmd_setmeal { my ( $date, $recipe_id ) = @_; my $mealtype = "lunch"; if ($date =~ /^Mon|Tue|Wed|Thu|Fri|Sat|Sun/) { my $wday; $wday = 1 if ($date =~ /^Mon/); $wday = 2 if ($date =~ /^Tue/); $wday = 3 if ($date =~ /^Wed/); $wday = 4 if ($date =~ /^Thu/); $wday = 5 if ($date =~ /^Fri/); $wday = 6 if ($date =~ /^Sat/); $wday = 7 if ($date =~ /^Sun/); my $dt = DateTime->now(); while ($dt->wday() != $wday) { $dt->add(days => 1); } $date = $dt->ymd(); } return unless $date =~ "^[0-9]{4}-[0-9]{2}-[0-9]{2}\$"; return -1 unless $recipe_id =~ "^[0-9]+\$"; if (get_recipe_name($recipe_id) ne 'NULL') { my $sql = "DELETE FROM plan WHERE date='$date' and mealtype='$mealtype';"; $db->do($sql); $sql = "INSERT INTO plan (date, mealtype, recipe_id) VALUES ('$date', '$mealtype', $recipe_id);"; $db->do($sql); } return 0; } sub cmd_randmeal { my ( $date ) = @_; my $recipe_id = get_random_recipe(); return cmd_setmeal($date, $recipe_id); } sub cmd_postpone { my ( $date, $gap ) = @_; my $mealtype = "lunch"; my $startdate; if($date) { return -1 unless $date =~ "^[0-9]{4}-[0-9]{2}-[0-9]{2}\$"; $startdate = DateTime::Format::ISO8601->parse_datetime( $date ); } else { $startdate = DateTime->now(); } $gap = 1; my $entries = $db->selectall_arrayref("SELECT date FROM plan WHERE date ". "BETWEEN '".$startdate."' and '2999-01-01' ORDER BY date DESC", { Slice => {} }); for my $entry ( @$entries ) { my $nextdate = DateTime::Format::ISO8601->parse_datetime($entry->{date}); $nextdate->add(days => $gap); $db->do("UPDATE plan SET date='".$nextdate->ymd()."' WHERE date='". $entry->{date}."';\n"); } } sub cmd_showplan { my ( $date ) = @_; my $mealtype = "lunch"; my $dt; if($date) { return -1 unless $date =~ "^[0-9]{4}-[0-9]{2}-[0-9]{2}\$"; $dt = DateTime::Format::ISO8601->parse_datetime( $date ); } else { $dt = DateTime->now(); } for (my $i = 0; $i < 7; $i++) { my $sql = "SELECT recipe_id FROM plan WHERE date='".$dt->ymd(). "' and mealtype='$mealtype';"; my @ids = $db->selectrow_array($sql); if ($ids[0]) { print $dt->ymd(), " ", get_recipe_name($ids[0]), ", ", get_recipe_uri($ids[0]), "\n"; } $dt->add(days => 1); } } sub cmd_randweek { # for (my $i = 0; $i < 5; $i++) { # $schedule[$i]->{'recipe'} = get_random_recipe; # } # # for (my $i = 0; $i < 5; $i++) { # print $schedule[$i]->{'day'}.": "; # print get_recipe_name($schedule[$i]->{'recipe'})."\n"; # my $contents = $db->selectall_arrayref("SELECT * FROM contents WHERE ". # "recipe_id=".$schedule[$i]->{'recipe'}); # unless (@$contents) { # print "OBSERVERA: Ingredienslista saknas för denna rätt!\n\n"; # } # } } sub cmd_help() { print "Help yet to be implemented\n"; } sub cmd_addrecipe { # FIXME Make it possible to provide name and uri as command line arguments # instead of solely interactive mode. my ( $recipe_name, $uri, $answer, $sql ); print "Recipe name: "; $recipe_name = ; chomp $recipe_name; print "E.g. http://stupid.domain.name/node/755, urn:isbn:9789127118348#102\n"; print "Recipe uri: "; $uri = ; chomp $uri; $sql = "INSERT INTO recipes (name, uri) VALUES ('$recipe_name', '$uri');"; print "$sql\n\n"; print "Add to database? (y/n): "; $answer = ; if ($answer eq "y\n") { $db->do($sql); } } # MAIN PROGRAM ################################################################ read_recipe_db; if ($ARGV[0]) { if ( $ARGV[0] eq "help") { print "Command failed!\n" unless (cmd_help >= 0); } if ( $ARGV[0] eq "addrecipe") { print "Command failed!\n" unless (cmd_addrecipe() >= 0); } if ( $ARGV[0] eq "setmeal") { print "Command failed!\n" unless (cmd_setmeal($ARGV[1], $ARGV[2]) >= 0); } if ( $ARGV[0] eq "randmeal") { print "Command failed!\n" unless (cmd_randmeal($ARGV[1]) >= 0); } if ( $ARGV[0] eq "showplan") { print "Command failed!\n" unless (cmd_showplan($ARGV[1]) >= 0); } if ( $ARGV[0] eq "postpone") { print "Command failed!\n" unless (cmd_postpone($ARGV[1]) >= 0); } } else { cmd_showplan; }