#!/usr/bin/perl # $RCSfile: recipe.pl,v $ $Revision: 1.6 $ $Name: $ # $Id: recipe.pl,v 1.6 2007/05/07 18:34:49 bpaauwe Exp $ # $Author: bpaauwe $ # $Date: 2007/05/07 18:34:49 $ # ---------------------------------------------------------------------------- # # Copyright (c) Bob Paauwe (2007) # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ---------------------------------------------------------------------------- # Recipe database access program # # Based on the arguments passed in, this will query information from # a recipe database and return the results. # # Initial goals: # 1) be able to query a list of recipe titles based on category and page # number. The results will get pushed to a fixed set of MainLobby # server variables. # # 2) be able to query a specific recipe and set a single MainLobby # server variable with the results. # # MainLobby Server variables used: # recipe - holds the text of the currently selected recipe # recipe_page - holds the current page of the recipe list # recipe_category - holds the currently selected recipe category # recipe_title - holds the title of the currently selected recipe # recipe_1 - These hold the titles for the page of recipe # . titles displayed in the list. # . # . # recipe_16 # # ***** Change the following two variables to match your configuration ****** # $MLSERVER_HOST = "localhost"; $RECIPE_DIR = "p:/cookbook/on-line/"; #**************************************************************************** # # PAGE_SIZE is the number of buttons in the scroll list # MAX_LINES is the number of lines in the recipe multi-line text box $PAGE_SIZE = 16; $MAX_LINES = 34; # Variables to set up a socket connection to the ML server. Used to # set variables. $AF_INET = 2; $SOCK_STREAM = 1; $sockadd = 'S n a4 x8'; ($name, $aliases, $proto) = getprotobyname ( 'tcp' ); ($name, $aliases, $type, $len, $thataddr) = gethostbyname ( $MLSERVER_HOST ); $that = pack ( $sockadd, $AF_INET, $port, $thataddr ); # # Incoming arguments # # arg0 - current page # # arg1 - category # arg2 - selected recipe (slot number, 1 - 10) # # arg2 is optional, if not specified, then a blank recipe string is returned. # # # Flow looks something like this: # # 1) Read raw data and build a list of recipe -> filename mappings # 2) based on incoming page number, set title variables # 3) if arg2 exist build recipe text and set variable else clear variable # # For a first pass, try creating separate files. Use the file name # as the recipe title. This makes the mapping easy also makes it # easy to update. if (@ARGV < 2) { print("Usage: $0 [selection] (@ARGV)\n"); exit 0; } if ($ARGV[3] =~ /next/) { $screen = 1; } else { $screen = 0; } # # Open the category directory based on the second argument passed in. Read # all the file names in the directory and store them in the @recipes array. # if (opendir(DIR, "${RECIPE_DIR}${ARGV[1]}/")) { @files = readdir(DIR); closedir(DIR); foreach $file (@files) { next if ($file =~ /^\./); next if ($file =~ /^\.\./); next if ($file =~ /\.jpg$/); # Skip JPG files next if ($file =~ /\.JPG$/); # Skip JPG files print("Adding $file to list\n"); push(@recipes, $file); } } else { print ("Failed to read directory $RECIPE_DIR\n"); exit 1; } # # Error check page value, if it's less than zero, reset it to zero and # set set the MLServer variable to zero. $page = $ARGV[0]; if ($page < 0) { $page = 0; set_variable_web("recipe_page~0"); } # # If argument is a page number then the first recipe to display in the # list is (page * PAGE_SIZE). However, if we want to scroll the list # one item at a time, then the first argument is the first recipe to # display, no calculation necessary. $first = $page * $PAGE_SIZE; for ($i = $first; $i < ($first + $PAGE_SIZE); $i++) { $var = sprintf("recipe_%d~%s", ($i - $first + 1), $recipes[$i]); set_variable_web($var); print("setting $i: $var\n"); } # If a specific recipe number is requested, format it and set the variable if ($ARGV[2]) { set_recipe($screen, $recipes[($ARGV[2] - 1) + $first], "${RECIPE_DIR}${ARGV[1]}/"); # # If there is a picture associated with this recipe, set a variable # with the image file name. # $picture_file = "${RECIPE_DIR}${ARGV[1]}/$recipes[($ARGV[2] - 1) + $first].jpg"; if (-f $picture_file) { set_variable_web("recipe_picture~$picture_file"); print("Setting: recipe_picture = $picture_file\n"); } else { # Try alternate case $picture_file = "${RECIPE_DIR}${ARGV[1]}/$recipes[($ARGV[2] - 1) + $first].JPG"; if (-f $picture_file) { set_variable_web("recipe_picture~$picture_file"); print("Setting: recipe_picture = $picture_file\n"); } else { set_variable_web("recipe_picture~"); } } } else { set_variable_web("recipe~What? You want more?"); } exit 0; # # Read a recipe file and format it as a MainLobby server variable # sub set_recipe { my ($screen, $file, $dir) = @_; my ($str); my ($ln_cnt); my ($more); $ln_cnt = 0; set_variable_web("recipe_more~"); if (open(R, "$dir/$file")) { while () { chomp; # FIXME: # My text box can only fit 34 lines of text. Currently this if ($screen) { if (++$ln_cnt > $MAX_LINES) { $str .= "$_
"; } } else { if (++$ln_cnt < $MAX_LINES) { $str .= "$_
"; } } } if ($ln_cnt > $MAX_LINES && !$screen) { $str .= "More ..."; $more = "recipe_more~$ARGV[0] $ARGV[1] $ARGV[2] next"; print("sending: $more\n"); set_variable_web($more); } # Set the recipe text server variable set_variable_web("recipe~$str"); print("recipe: $str\n"); # Set the recipe title server variable set_variable_web("recipe_title~$file"); print("recipe_title: $file\n"); } else { print("Failed to open $dir/$file\n"); } } # # Set a variable in the MainLobby Server using the built-in web server # sub set_variable_web { my ($variable) = @_; # web server port is 6246 $that = pack ( $sockadd, $AF_INET, 6246, $thataddr ); if ( socket ( S, $AF_INET, $SOCK_STREAM, $proto ) ) { if ( connect ( S, $that ) ) { select ( S ); $| = 1; select ( stdout ); $variable =~ s/ /%20/g; print S "GET /command?SetVariable|$variable\n\n"; } while ( ) { } close (S); } } # # Set a variable in the MainLobby Server by opening a socket connection and # writing the set variable command. NOTE: This function is not being used, # the web based method above seems a bit better. # sub set_variable { my ($variable) = @_; if ( socket ( S, $AF_INET, $SOCK_STREAM, $proto ) ) { if ( connect ( S, $that ) ) { select ( S ); $| = 1; select ( stdout ); print S "SetVariable|$variable\r\n"; } while ( ) { } close (S); } sleep 4; }