#!/usr/bin/env perl # Dit is een routeplanner die gebruikt maakt van Geo::Google # om een route tussen verschillende adressen te berekenen. # # De adressen worden allen steeds opgeslagen in een appart bestand, # dit bestand zal automatisch gecreerd worden indien dit # nog niet bestaat. # # Om dit programma te kunnen gebruiken moet Geo::Google beschikbaar # zijn op de computer. # # Author: MADnificent # Version: 0.0.1 use Geo::Google; # Globale variabelen $DB_FILE = '.routeplanner.db'; # Voegt een adres toe aan de database van het programma. # # @pre @_ = (naam, straat, nr, stad, land) sub voegAdresToe { open (DB, ">>$DB_FILE") || die "could not open database file"; print DB maakDbRecord(@_); close (DB); } # Drukt al de adressen af op het scherm. # # @pre file_exists($DB_FILE) sub drukAdressenAf { my($adressen) = dbGrootte(); print "----------------------------------------------------------\n"; print " Er zitten $adressen adressen in de database \n"; print "----------------------------------------------------------\n"; print "\n"; drukAdresAf( (0 ... ($adressen-1)) ); } # Drukt het gevraagde adres af uit de database # # @pre @_[i] < dbGrootte # @pre voor onbekende adressen wordt er een lege # plaats afgedrukt (even groot dan een geheel # record zou innemen). # @pre fileExists($DB_FILE) # # @post De gevraagde adressen zijn afgedrukt sub drukAdresAf { my(@params) = @_; my($cur); tussenRegel(); foreach $cur (@params) { if($cur >=0 && $cur < dbGrootte()) { my(@adres) = geefAdres($cur); print "nr:$cur\n"; print " -- $adres[0] \n"; print " --- $adres[1] $adres[2] \n"; print " --- $adres[3], $adres[4] \n"; tussenRegel(); } else { print "\n\n\n\n"; } } } # Vervangt het record met de gegeven geheugenplaats door het nieuwe # gegeven record # # @pre @_[0] = $nr; # @pre $nr < dbGrootte; # @pre @_[1 .. $#_] = ($naam, $straat, $nummer, $stad, $land) # # @post geefAdres($nr) == ($naam, $straat, $nummer, $stad, $land) sub vervangAdres { my($nr) = $_[0]; $nr = dbGrootte() unless adresBestaat($nr); # Als het id niet bestaat, voegen we het toe op het einde vd database. my($dbRegel) = maakDbRecord(@_[1 .. $#_]); open (DB, $DB_FILE); my(@data) = ; close (DB); $data[$nr] = $dbRegel; open (DB, ">$DB_FILE"); print DB @data; close (DB); } # Geeft de data van een bepaald adres-nummer terug. # # @pre @_ = ($nr) # @pre $nr < dbGrootte # # @ret ($naam, $straat, $nummer, $stad, $land) sub geefAdres { open (DB, $DB_FILE); my(@data) = ; close (DB); parseRecord( $data[$_[0]] ); } # private # Verwijdert spaties aan het begin en aan het einde van de gegeven strings # # @post $_[i] =~ /^/S*.*/S*$/ sub trim { my(@return); my(@lijst) = @_; my($cur); foreach $cur (@lijst) { $cur =~ s/^\s*//; $cur =~ s/\s*$//; push(@return, $cur); } return @return; } # private # Haalt de data uit een lijn in de database (of een invoerlijn van de user) # # @pre @_ = ($dbRecord) # @pre $dbRecord =~ /\w[\w|\s]*::\w[\w|\s]*::\s*\d+\s*::\w[\w|\s]*::\w[\w|\s]*/ # @pre $dbRecord =~ /[^:]*::[^:]*::[^:]*::[^:]*::[^:]*/ # || $dbRecord =~ /\w[\w|\-|\s]*::[a-zA-Z][a-zA-Z|\-|\s]*\s*\d+\s*::\w[\w|\-|\s]*::\w[\w|\-|\s]*/ # # @ret ($naam, $straat, $nummer, $stad, $land) sub parseRecord { if($_[0] =~ /([^:]*)::([^:]*)::([^:]*)::([^:]*)::([^:]*)/) { return trim($1 , $2 , $3 , $4 , $5); } elsif($_[0] =~ /(\w[\w|\-|\s]*)::([a-zA-Z][a-zA-Z|\-|\s]*)(\s*\d+\s*)::(\d+\s+\w[\w|\-|\s]*)::(\w[\w|\-|\s]*)/) { return trim($1 , $2 , $3 , $4 , $5); } } # private # Geeft weer of de gegeven record-string voldoet aan de syntactische # voorwaarden om in de database gestoken te kunnen worden, # of niet. # # @pre @_ = $recordString sub isDbRecord { my($recordString) = $_[0]; # TODO Users _could_ enter newlines in this data... that would make the layout badd, and wouldn't be a # valid address either... if($recordString =~ /\w[\w|\-|\s]*::[a-zA-Z][a-zA-Z|\-|\s]*\s*\d+\s*::\d+\s*\w[\w|\-|\s]*::\w[\w|\-|\s]*/) { return 1; } # TODO This is not idiot-proof if($recordString =~ /[^:]*::[^:]*::[^:]*::[^:]*::[^:]*/) { return 1; } return 0; } # private # Maakt een van de gegeven data een string die in de database past. # # @pre @_ = ($naam, $straat, $nr, $stad, $land) # # @ret databse string for the given record sub maakDbRecord { "$_[0]::$_[1]::$_[2]::$_[3]::$_[4]\n"; } # Zoekt het aantal elementen in de database van het programma. # # @pre file_exists(DB_FILE) == true; # # @ret adressen in de database. sub dbGrootte { my($lijnen) = 0; open (DB, $DB_FILE); while() { $lijnen++; } return $lijnen; } # Geeft weer of een bepaald adres al dan niet in de database zit # indien het dbNummer gegeven is. # # @pre @_ = ($dbNr) sub adresBestaat { my ($dbNr) = $_[0]; return 1 if ($dbNr>=0 && $dbNr; splice(@data, $rem_line, 1); close (DB); open (DB, ">$DB_FILE"); print DB @data; close (DB); } # Berekent de route tussen twee adressen (die gegeven zijn in een formaat # dat Geo::Google begrijpt. # # @pre @_ = ($adresA, $adresB); # @pre $_[i] beschrijft routen die Geo::Google begrijpt en die bestaan. # | typeOf($_[i]) == 'String'; # # @ret Pad dat de route beschrijft. # je kan de data uit dit pad halen door @ret->segments(); # Uit elk van deze segmenten kan je # o -> text Tekstuele omschrijving # o -> html Langere omschrijving sub berekenRoute { my ($geo) = Geo::Google->new(); print "adresstrings: \n $_[0] \n $_[1] \n"; my ($locA) = $geo->location( address => $_[0] ); my ($locB) = $geo->location( address => $_[1] ); my ($path) = $geo->path( $locA , $locA , $locB , $locB ); return $path; } # Berkent de route tussen twee adressen (met het adresnummer gegeven) # # @pre @_ = ($adresA , $adresB); # @pre $_[i] < dbGrootte # # @ret Array van strings die de route in menselijke taal beschrijven. sub geefRouteBeschrijving { my($adresA, $adresB) = ( $_[0] , $_[1] ); # haal de adressen uit de databank my(@dataA) = geefAdres( $adresA ); my(@dataB) = geefAdres( $adresB ); # bouw adresstrings op uit de data my($stringA) = "$dataA[2] $dataA[1], $dataA[3], $dataA[4]"; my($stringB) = "$dataB[2] $dataB[1], $dataB[3], $dataB[4]"; # geef de data door aan de berekenfunctie my(@route) = berekenRoute($stringA, $stringB)->segments(); # haal de tekstStrings uit de berekeningen my(@routeBeschrijving); my($seg); foreach $seg (@route) { # $seg->html zou een beter beschrijving kunnen opleveren. my($text) = $seg->text; push(@routeBeschrijving, $text); } return @routeBeschrijving; } # Geeft weer of het mogelijk is een route te berekenen in # de huidige databank. sub kanRouteBerekenen { if(dbGrootte>=2) { return 1; } return 0; } # Geeft zeer of er records zijn die afgedrukt kunnen worden sub heeftRecords { if(dbGrootte>0) { return 1; } return 0; } ##### Hier staan de modi waarin de gebruiker data kan invoeren/uitvoeren ##### ### Hulpcode om data van de gebruiker te parsen naar acties uit het systeem # Afhandeling van de routeberekening en afdruk # # @pre @_ = ($adresA , $adresB); # @pre 0 <= $_[i] < dbGrootte # # @post De weg werd berekend en afgedrukt sub geefRoute { my($adresA, $adresB) = ($_[0], $_[1]); die "Gelieve correcte adresnummers in te geven" unless ($adresA=0 && $adresB>=0) && ($adresA != $adresB); print "De route tussen adres $adresA en $adresB zal berekend worden.\n"; drukAdresAf($adresA, $adresB); @beschrijving = geefRouteBeschrijving($adresA, $adresB); my($opdracht); foreach $opdracht (@beschrijving) { print "$opdracht\n"; } } # Update het gevraagde record met de gegeven data. # # @pre De eerste meegegeven waarde is de nummer van het record dat aangepas zal worden. # |$_[0] = $nr # @pre $nr >= 0 && $nr < dbGrootte # # @post In het record zal de nieuwe data staan (aangegeven door $nNaam, $nStraat, ...) # |geefAdres($nr)==($nNaam,$nStraat,$nNummer,$nStad,$nLand sub updateRecord { # haal de meegegeven data binnen my($nr) = $_[0]; my(@data) = @_[1 ... $#_]; return 0 unless dbGrootte > $nr; # parse de data uit de functie my(@record) = geefAdres($nr); my(@curTag); while($curTag = shift(@data)) { my(@value) = shift(@data); if($curTag eq "naam") { $record[0] = @value; } elsif($curTag eq "straat") { $record[1] = @value; } elsif($curTag eq "nr" || $curTag eq "nummer" || $curTag eq "straatnr" || $curTag eq "straatnummer") { $record[2] = @value; } elsif($curTag eq "stad" || $curTag eq "dorp" || $curTag eq "gemeente") { $record[3] = @value; } elsif($curTag eq "land") { $record[4] = @value; } } # vervang het oude record bij door het nieuwe record vervangAdres($nr, @record); return 1; } # Toont een scheidingsregel tussen verschillende items/records/whatever sub tussenRegel { print "---------------------------------------------------------------\n"; } ### Functies voor de interactieve modus # Toont een record-browser waarmee gebruikers records kunnen opzoeken # en eventueel selecteren. # # @pre @_ = ($menustructuur, $selecteerbaar, $beginID) # @var $menustructuur # Dit is de structuur zonder de toevoeging van # " > browser" of van " > selector"; # @var $selecteerbaar # Dit toont aan of de opties ivm selecteren van items # aangezet moeten worden. De browser geeft eenderhoe # de laatst geziene waarde van de gebruiker terug. # @var $beginID # Dit is de ID die in het begin centraal zal staan in de browser. sub toonBrowser { my($menustructuur , $selecteerbaar, $beginID) = @_; # Verzekerd een correcte beginID $beginID = $beginID < 0 ? 0 : $beginID; $beginID = $beginID >= dbGrootte() ? (dbGrootte()-1) : $beginID; # bouw menu op my($menu) = $menustructuur . ($selecteerbaar ? " > selector" : " > browser"); my(@help) = ( $menu, "De recordbrowser is een systeem waarin de verschillende", "records kunnen bekeken" . ($selecteerbaar ? " en geselecteerd" : "") . " worden.", "[j]", "de letter j zal de lijst een letter naar beneden doen gaan.", "Indien voor de letter j een getal staat, dan zal er net zoveel", "items naar beneden gegaan worden dan dat getal groot is.", "[k]", "de letter k zal de lijst een letter naar boven doen gaan.", "Indien voor de letter een getal staat, dan zal er net zoveel", "items naar boven gegaan worden dan dat getal groot is.", "[h]", "de letter h zal dit help-menu nogmaals te voorschijn toveren.", "[niets]", "een lege input zal de laatste input heruitvoeren", "dit is dus niet het woordje 'niets' ;-)", "[x]", "stopt de browser."); if($selecteerbaar) { push(@help, "Het middelste item is dan geselecteerd (u kan het item-nummer", "ook bekijken in de responsbalk."); } # Toon help als introductie toonMenu (@help); # Toon de browser my($curID) = $beginID; my($prevInput); # this is the input the user gave right before this input. my($repeat); browserSnap($menu, $selecteerbaar, $curID); my($line) = ""; until($line =~ /x/) { tussenRegel(); # catch the repeat-action if($repeat) { $line = $prevInput; $repeat = 0; } else { print "Uw input: "; $line = ; } #scroll down (numbers go up) if($line =~ /(\d*)j/) { if($1) { $curID += $1; } else { $curID += 1; } } #scroll up (numbers go down) elsif($line =~ /(\d*)k/) { if($1) { $curID -= $1; } else { $curID -= 1; } } #toon help elsif($line =~ /h/) { toonMenu (@help); } elsif($line eq "\n") { $repeat = $repeat ? 0 : 1; # this solves the pressing of every time } #vang fouten in $curID op $curID = $curID >= dbGrootte() ? (dbGrootte()-1) : $curID; $curID = $curID < 0 ? 0 : $curID; $prevInput = $line unless $repeat; #toon het nieuwe venster browserSnap($menu, $selecteerbaar, $curID); } return $curID; } # Toont een bepaald venster van de browser. # # @pre @_ = ($menu, $selecteerbaar, $centraleID); # @pre 0 <= $centralID < dbGrootte # @pre $menu = /[\w+\s>]*\w+/ sub browserSnap { my($menu , $selecteerbaar , $centraleID) = @_; printStructuur($menu); drukAdresAf(($centraleID-1)...($centraleID+1)); print "huidige ".($selecteerbaar?"geselecteerde ":"")."ID : $centraleID\n"; } # Toont een menu op het scherm, en geeft de invoer van de gebruiker # terug weer # # @pre @_ = ($menu , @inleiding, @optiesEnOmschrijvingen) # @pre $menu = "menu > submenu > subsubmenu ..." # @pre @inleiding = ("dit is een leidende", "tekst die ...) # @pre @optiesOmschrijving = ("[optie]", "regelBijOptie", "regel bij optie", # "[ander]", "regel bij optie, # "[nog]", "r1", "r2", "r3", ...); # @pre exists(@optiesOmschrijving) # # @ret Een optie die bij de optiesOmschrijving stond sub toonMenu { my(@params) = @_[1 ... $#_]; my($beginOpties)=0; while(!($params[$beginOpties] =~ /^\[\w+\]$/)) { $beginOpties++; } my(@inleiding) = @params[0 ... ($beginOpties-1)]; my(@opties) = @params[$beginOpties ... $#params]; print "\n\n\n"; tussenRegel; printStructuur($_[0]); printInleiding(@inleiding); tussenRegel; printOpties(@opties); tussenRegel; print "Uw keuze: "; my($in); $in = ; chop($in); return $in; } # Print de opties die bij een bepaald menu horen. # # @pre @_ = ($optie1, $introlijn1, $introlijn2, ..., # $optie2, $introlijn, ..., # ...); # @pre $optie =~ /^\[\w+\]$/ sub printOpties { my($cur); foreach $cur (@_) { print " " unless $cur =~ /^\[\w+\]$/; print "$cur\n"; } } # Print de inleidende informatie die bij de menus gegeven wordt. # Indentatie wordt automatisch afgehandeld. # # @pre @_ = ("eerste regel", "tweede regel", ...) sub printInleiding { my(@args) = @_; print shift(@args), "\n"; my($regel); while($regel = shift(@args)) { print " $regel\n"; } } # Print de structuur af die de gebruiker toont waar hij zich bevind. # # @pre @_ = ($structuur, ...); # @pre $structuur = "menu > submenu > subsubmenu"; sub printStructuur { tussenRegel; print "MENU :: $_[0]\n"; tussenRegel; } # Vraagt de gebruiker een input die correct is (moet voldoen aan de # meegegeven regex # # @pre @_ = ($regex, @vraag); sub vraagGebruikerRegex { my($regex, @vraag) = @_; my($line); $line = vraagGebruiker(0, @vraag); while( !($line =~ $regex) ) { $line = vraagGebruiker(1, @vraag); } return $line; } # Stelt een vraag een de gebruiker en heeft een interface voor het heralen # van vragen aan de gebruiker. # # @pre @_ = ($herhaling, @vraag); # @pre @vraag = ($regel1, $regel2, ...); sub vraagGebruiker { my($herhaling, @vraag) = @_; if(!$herhaling) { $aantalKeerDatGebruikerVraagKreeg = 0; toonVraagGebruiker(@vraag); } elsif($aantalKeerDatGebruikerVraagKreeg < 5) { $aantalKeerDatGebruikerVraagKreeg++; print "Uw input was niet correct, probeer nogmaals.\n"; } else { $aantalKeerDatGebruikerVraagKreeg = 0; print "Uw input was niet correct, de vraag was: \n"; toonVraagGebruiker(@vraag); } print "Uw input: "; my($input); $input = <>; chop($input); print "\n"; return $input; } # Print een gestelde vraag voor de gebruiker af # # @pre @_ = ($regel1, $regel2, ...); sub toonVraagGebruiker { print "\n"; tussenRegel; my(@regels) = @_; my($regel) = shift(@regels); print "$regel\n"; while($regel = shift(@regels)) { print " $regel\n"; } } # Vraagt de gebruiker om de naam van een gebruiker # in te voeren. # # @pre @_ = ($menu) # @var $menu # Het menu wordt ingegeven tot aan de parent van # dit gedeelte. Dit wordt automatisch aangevuld # tot een bruikbare naam voor deze module. # e.g: $menu eq "main > add" sub enterUser_naam { my($menu) = "$_[0] > naam"; my($line); printStructuur($menu); $line = vraagGebruikerRegex( '\w[\w|\-|\s]*', "Gelieve de naam van de gebruiker in te vullen."); return $line; } # Vraagt de gebruiker om de straat en nummer van een gebruiker # in te voeren. # # @pre @_ = ($menu) # @var $menu # Het menu wordt ingegeven tot aan de parent van # dit gedeelte. Dit wordt automatisch aangevuld # tot een bruikbare naam voor deze module. # e.g: $menu eq "main > add" # # @ret ($street, $digit) sub enterUser_straat { my($menu) = "$_[0] > straat"; printStructuur($menu); my(@vraag) = ( "Gelieve de straatnaam en de nummer van de straat", "(gescheiden door een spatie) in te geven."); my($line) = vraagGebruiker(0,@vraag); my($correct) = ($line =~ /([a-zA-Z][a-zA-Z|\-|\s]*)\s*(\d+)\s*/); my($street) = $1; my($digit) = $2; while(!$correct) { $line = vraagGebruiker(1,@vraag); $correct = ($line =~ /([a-zA-Z][a-zA-Z|\-|\s]*)\s*(\d+)\s*/); $street = $1; $digit = $2; } return ($1, $2); } # Vraagt de gebruiker om de stad van een gebruiker # in te voeren. # # @pre @_ = ($menu) # @var $menu # Het menu wordt ingegeven tot aan de parent van # dit gedeelte. Dit wordt automatisch aangevuld # tot een bruikbare naam voor deze module. # e.g: $menu eq "main > add" sub enterUser_stad { my($menu) = "$_[0] > stad"; printStructuur($menu); my($line) = vraagGebruikerRegex( '\d+\s+\w[\w|\-|\s]*', "Gelieve de naam van de stad/gemeente van de gebruiker", "in te geven, voorafgegaan door de postcode"); return $line; } # Vraagt de gebruiker om het land van een gebruiker # in te voeren. # # @pre @_ = ($menu) # @var $menu # Het menu wordt ingegeven tot aan de parent van # dit gedeelte. Dit wordt automatisch aangevuld # tot een bruikbare naam voor deze module. # e.g: $menu eq "main > add" sub enterUser_land { my($menu) = "$_[0] > land"; printStructuur($menu); my($line) = vraagGebruikerRegex( '\w[\w|\-|\s]*', "Gelieve het land van de gebruiker in te geven"); return $line; } # Vraagt de gebruiker om een naam in te voeren. # Deze module handeld het invoegen van een naam af # op verscheidene manieren (die hier dus handig # gegroepeerd staan). # # @pre @_ = ($menu , @intro) # @var @intro is een array met verschillende strings # die samen de introductie uitleggen over het waarom # van de data-invoer door de gebruiker. # @var $menu is de menustructuur die bovenaan de selectie # van de data-invoer zal getoond worden. sub interactiveEnterUser { my($menu, @intro) = @_; my(@addMenu) = ("$menu > opties", @intro, "[lijn]", "geeft een gebruiker in op 1 lijn", "eg: Steward John::Spring Avenue 67::3476 Springfield::Isle of Man", "[individueel]", "Het systeem zal hier verscheidene vragen stellen", "tot de gebruiker volledig gedefinieerd is.", "[leave]", "Toch geen gebruiker definieren?", "Kies exit om naar het vorige menu weer te keren."); # Toon het keuzemenu tot de gebruiker een geldige invoer heeft gegeven. my($input); while( !($input =~ /[lijn|individueel|leave]/) ) { $input = toonMenu(@addMenu); } return if $input =~ /leave/; # Gebruikte veriabelen my(@regex, @vraag, $line); # Voeg een gebruiker toe in n lijn if($input =~ /lijn/) { $line = vraagGebruikerRegex( '\w[\w|\-|\s]*::[a-zA-Z][a-zA-Z|\-|\s]*\s*\d+\s*::\d+\s+\w[\w|\-|\s]*::\w[\w|\-|\s]*', "Gelieve de data in te vullen in een string:", "eg: Steward John::Spring Avenue 67::3476 Springfield::Isle of Man"); return parseRecord($line); } # Voeg een gebruiker toe aan de hand van individuele vragen else { my(@gebruiker); #naam van de gebruiker $line = enterUser_naam($menu); push (@gebruiker, $line); #straat van de gebruiker push (@gebruiker, enterUser_straat($menu)); #stad van de gebruiker push (@gebruiker, enterUser_stad($menu)); #land van de gebruiker push (@gebruiker, enterUser_land($menu)); return @gebruiker; } } # Afhandling van de add-actie van de gebruiker sub interactiveAdd { my(@user) = interactiveEnterUser ("main > add", "Voeg een gebruiker toe aan de database"); if(@user) { voegAdresToe(@user); } } # Afhandling van de update-actie van de gebruiker sub interactiveUpdate { my($input, $leave); my($menu) = "main > wijzig"; my(@menuInhoud) = ( $menu, "Hier kan u de verschillende methoden kiezen", "waarop u een gebruiker kan selecteren uit", "de databank, om deze later aan te passen.", "[browser]", "Deze optie start de browser die u het te", "wijzigen element zal laten kiezen uit", "de lijst met adressen.", "[getal]", "Indien u een getal intypt, zal het gevraagde", "record verschijnen ter controle, en kan", "onmiddelijk overgegaan worden in het wijzigen", "van het record (iets sneller als je de ID van", "het record reeds kent).", "[leave]", "Heeft u zich bedacht, en wil u toch geen gebruiker", "verwijderen? Of heeft u ondertussen voldoende", "gebruikers de records uit gesmeten?", "Kies dan om weer in het vorige", "menu terecht te komen"); # het gekozen record my($chosenRecord); my($recordGekozen); until($leave) { $recordGekozen = 0; until($recordGekozen || $leave) { $input = toonMenu(@menuInhoud); if($input =~ /browser/) { $chosenRecord = toonBrowser($menu, 1, 0); printStructuur("$menu > controle"); drukAdresAf($chosenRecord); print "Bent u zeker dat u dit adres wil wijzigen? (Y/n)"; my($check); $check = <>; $recordGekozen = 1 unless $check =~ /[n|N]/; } elsif($input =~ /(\d+)/) { print "$input\n"; $chosenRecord = $1; if(adresBestaat($chosenRecord)) { drukAdresAf($chosenRecord); print "Bent u zeker dat u dit adres wil wijzigen? (Y/n)"; my($check); $check = <>; $recordGekozen = 1 unless $check =~ /[n|N]/; } else { print "Oeps, dat record bestaat niet :-)\n"; } } elsif($input =~ /leave/) { $leave = 1; } else { print "Oeps, die optie bestaat niet, probeer nog eens :-)\n"; } } # We don't want to adjust records if we want to leave next if $leave; my($doneWithOperations)=0; my($menu_mod) = "$menu > ID:$chosenRecord"; until($doneWithOperations) { my(@user) = geefAdres($chosenRecord); $input = toonMenu( $menu_mod, "Hier kan u kiezen welke eigenschappen u wil aanpassen", "van het door u geselecteerde adres.", "[naam]", "Pas de naam aan van de persoon.", "[straat]", "Pas de straat aan van het adres.", "[stad]", "Pas de stad aan van het adres.", "[land]", "Pas het land aan van het adres.", "[stop]", "Stopt met aanpassingen aan het adres,", "en gaat weer naar het vorige menu."); if($input=~/naam/) { my($naam) = enterUser_naam($menu_mod); $user[0] = $naam; vervangAdres($chosenRecord, @user); } elsif($input=~/straat/) { my($straat, $nr) = enterUser_straat($menu_mod); @user[1,2] = ($straat, $nr); vervangAdres($chosenRecord, @user); } elsif($input=~/stad/) { my($stad) = enterUser_stad($menu_mod); $user[3] = $stad; vervangAdres($chosenRecord, @user); } elsif($input=~/land/) { my($land) = enterUser_land($menu_mod); $user[4] = $land; vervangAdres($chosenRecord, @user); } elsif($input=~/stop/) { $doneWithOperations = 1; } else { print "Oeps, u kees een opdracht die niet beschikbaar was.\n"; } } } } # Afhandeling van de Print actie van de gebruiker sub interactivePrint { my ($input); my ($db_max) = (dbGrootte()-1); my ($title) = "main > print"; my (@menu) = ( $title, "Selecteer 1 van de onderstaande opties om", "de door u gewenste data af te drukken.", "Druk op om de browser te starten!", "[alles]", "Deze optie drukt al de gekende records af.", "[nummers]", "U kan ook opteren om verscheide nummers,", "gescheiden door een spatie in te typen", "de records die hier aan voldoen zullen dan", "afgedrukt worden.", "net als voor de reeks moeten de getallen zich", "bevinden tussen 0 en $db_max.", "[browse]", "Met deze optie kan u rustig door de lijst", "van namen scrollen.", "[leave]", "Wil u liever toch geen records afdrukken?", "kies dan deze optie om naar het vorige menu", "weer te keren."); my($success) = 0; until($success) { $input = toonMenu(@menu); # Toon alles if($input =~ /alles/) { drukAdressenAf; $success++; print "druk om weer naar het vorige menu te keren\n"; <>; } # Druk een aantal records af elsif($input =~ /[\d+\s+]+/) { my(@numbers) = split(/\s+/, $input); my(@records); # zet de correcte adressen in @records my($record); foreach $record (@numbers) { if($record >= 0 && $record <= $db_max) { push(@records, $record); } } drukAdresAf(@records); $success++; print "druk enter om weer naar het vorige menu te keren\n"; <>; } # Browse elsif($input =~ /browse/) { toonBrowser($title, 0, 0); } # Ga uit de lus elsif($input =~ /leave/) { $success++; print "leave";} else { # Foutieve input gekregen print "Oeps, u heeft foutieve input ingegeven, probeer nogmaals\n"; print " druk om weer een keuze te kunnen maken.\n"; <>; } } } # Afhandeling van de delete-actie van de gebruiker. sub interactiveDelete { my($input, $leave); my($menu) = "main > delete"; until($leave) { $input = toonMenu( $menu, "Hier kan u de verschillende methoden kiezen", "waarop u een gebruiker kan verwijderen uit", "de databank.", "[browser]", "Deze optie start de browser die u het te", "verwijderen element zal laten kiezen uit", "de lijst met adressen.", "[getal]", "Indien u een getal intypt, zal het gevraagde", "record verschijnen ter controle, en kan", "onmiddelijk overgegaan worden in het verwijderen", "van het record (iets sneller als je de ID van", "het record reeds kent).", "[leave]", "Heeft u zich bedacht, en wil u toch geen gebruiker", "verwijderen? Of heeft u ondertussen voldoende", "gebruikers de records uit gesmeten?", "Kies dan om weer in het vorige", "menu terecht te komen"); my($chosenRecord); if($input =~ /browser/) { $chosenRecord = toonBrowser($menu, 1, 0); printStructuur("$menu > controle"); drukAdresAf($chosenRecord); print "Bent u zeker dat u dit adres wil verwijderen? (Y/n)"; my($check); $check = <>; verwijderRegel($chosenRecord) unless $check =~ /[n|N]/; } elsif($input =~ /(\d+)/) { print "$input\n"; $chosenRecord = $1; if($1>=0 || $1 < dbGrootte()) { drukAdresAf($chosenRecord); print "Bent u zeker dat u dit adres wil verwijderen? (Y/n)"; my($check); $check = <>; verwijderRegel($chosenRecord) unless $check =~ /[n|N]/; } else { print "Oeps, dat record bestaat niet :-)\n"; } } elsif($input =~ /leave/) { $leave = 1; } else { print "Oeps, die optie bestaat niet, probeer nog eens :-)\n"; } } } # Afhandeling van de route-actie van de gebruiker sub interactiveRoute { my(@adress, $input, $leave); my($menu) = "main > route"; until($leave) { @adress = (); my($grootte) = 0; until($grootte==2 || $leave) { print "grootte :: $grootte, of $adress\n"; print "adress :: @adress\n"; $input = toonMenu( $menu, "Hier kan u de verschillende methoden kiezen", "waarop u een gebruiker kan selecteren als ".($grootte==0?"vertrek":"bestemming"), "voor de route.", "[browser]", "Deze optie start de browser, waarin u", "eenvoudig het adres dat u zoekt kan", "selecteren", "[getal]", "Indien u een getal intypt, zal het gevraagde", "record verschijnen ter controle, en kan", "onmiddelijk overgegaan worden tot het gebruiken", "van het adres voor de routebepaling. Indien u", "het adres kent bij nummer, is dit een snellere", "methode.", "[leave]", "Heeft u zich bedacht, en wil u toch geen gebruiker", "verwijderen? Of heeft u ondertussen voldoende", "gebruikers de records uit gesmeten?", "Kies dan om weer in het vorige", "menu terecht te komen"); my($gebruiker); if($input =~ /browser/) { $gebruiker = toonBrowser($menu, 1, 0); printStructuur("$menu > controle"); drukAdresAf($gebruiker); print "Bent u zeker dat u dit adres wil gebruiken \n"; print ("als ".($grootte==0?"vertrek":"bestemming")."? (Y/n) "); my($check); $check = <>; push(@adress, $gebruiker) unless $check =~ /[n|N]/; } elsif($input =~ /(\d+)/) { $gebruiker = $1; if($gebruiker>=0 && $gebruiker controle"); drukAdresAf($gebruiker); my($print) = "Bent u zeker dat u dit adres wil gebruiken \n"; $print .= ("als ".($grootte==0?"vertrek":"bestemming")."? (Y/n) "); print $print; my($check); $check = <>; push(@adress, $gebruiker) unless $check =~ /[n|N]/; } else { print "Oeps, dit adres bestaat niet, probeer nogmaals.\n"; } } elsif($input =~ /leave/) { $leave = 1; } else { print "Oeps, u gaf een onbestaande optie, probeer nogmaals.\n"; } $grootte = @adress; } if(!$leave) { printStructuur($menu." > afdruk"); geefRoute(@adress); print "druk op een toets om weer naar het menu te gaan"; <>; } } } ### Afhandeling van de acties van de gebruiker # Een interactieve modus waarin de gebruiker zijn opties kan bekijken # en zo operaties op de data kan uitvoeren. # # @post Gebruiker zal gevraagd worden data in te voeren, # die overeen stemt met de acties die hij wil ondernemen. sub interactieveModus { tussenRegel; print "Welkom in de interactieve modus\n"; tussenRegel; my($input) = ""; my(@menu); while($input ne "quit") { # We need to calculate the menu every time (after the add, the options may change). @menu = ( "main", "Gelieve uit de opties (geschreven tussen de [ ]) een keuze te maken,", "en deze in te typen (gevolgd door enter)", "[add]", "voeg een gebruiker toe aan de database" ); #---------- AVOIDS USERS TO CHOOSE UNAVAILABLE OPTIONS -------------# if( heeftRecords() ) { push(@menu, "[update]", "geven om uw keuze te maken (volgen door ).", "update de gegevens van een gebruiker", "[print]", "drukt de gegevens van gebruiker(s) af", "[delete]", "verwijdert de gegevens van een gebruiker"); } if( kanRouteBerekenen() ) { push(@menu, "[route]", "geeft de route tussen twee gebruikers"); } #---------- AVOIDS USERS TO CHOOSE UNAVAILABLE OPTIONS -------------# push(@menu, "[quit]", "sluit de applicatie af"); $input = toonMenu( @menu ); if($input =~ /add/) { interactiveAdd(); } elsif($input =~ /update/) { interactiveUpdate(); } elsif($input =~ /print/) { interactivePrint(); } elsif($input =~ /delete/) { interactiveDelete(); } elsif($input =~ /route/) { interactiveRoute(); } } exit; } # De gebruiker heeft al de data van de uit te voeren bewerkingen # reeds op de commandline ingegeven. # Deze data zal geparsed worden, en de bewerkingen zullen # uitgevoerd worden. # # @post De door de gebruiker ingegeven data zal geparsed worden sub cliModus { #TODO Finish method stub tussenRegel; print "Welkom in de cli modus\n"; print "Uw argumenten waren @ARGV \n"; tussenRegel; # adres(sen) afdrukken if($_[0] eq "print" || $_[0] eq "-p") { heeftRecords() || die "Er zijn geen records in de database!"; if(exists($_[1]) && $_[1] < dbGrootte) { drukAdresAf(@_[1 .. $#_]); } else { drukAdressenAf; } } # browser starten elsif($_[0] eq "-b" || $_[0] eq "browse" || $_[0] eq "browser") { heeftRecords() || die "U kan geen browser starten in een leeg adressenbestand"; # start de browser op het gegeven adres if(exists($_[1])) { toonBrowser("cli" , 0 , $_[1]); } else { toonBrowser("cli" , 0 , 0); } } # adres toevoegen elsif( exists($_[1]) && ($_[0] eq "-a" || $_[0] eq "add" || $_[0] eq "voeg toe" || $_[0] eq "voegtoe") ) { isDbRecord($_[1]) || die "Verkeerd geformatteerde of onvolledige input gegeven"; voegAdresToe( parseRecord($_[1]) ); } # adres update elsif($_[0] eq "update" || $_[0] eq "wijzig" || $_[0] eq "-u") { updateRecord( @_[1 ... $#_] ) || die "Het gegeven adres bestaat niet"; } # adres substitute elsif($_[0] eq "-s" || $_[0] eq "subs" || $_[0] eq "vervang" || $_[0] eq "substitute" || $_[0] eq "verv") { isDbRecord($_[2]) || die "Verkeerd geformatteerde of onvolledige input gegeven"; vervangAdres( $_[1] , parseRecord($_[2]) ); } # adres verwijderen elsif($_[0] eq "-d" || $_[0] eq "del" || $_[0] eq "delete" || $_[0] eq "verwijder") { adresBestaat($_[1]) || die "Te verwijderen adres bestaat niet."; verwijderRegel( $_[1] ); } # bereken route elsif($_[0] eq "-r" || $_[0] eq "-w" || $_[0] eq "route" || $_[0] eq "weg") { #TODO The new Geo::Google should catch this one, test this geefRoute( @_[1 ... $#_] ); } } # private # update een bepaald gegeven uit een record # De help die bij het commando hoort zal worden weergegeven. # # @post De help wordt op het scherm geprint. sub cliHelp { print "Dit is de help van het 'routes' commando.\n"; tussenRegel; print "Het commando kan opgeroepen worden op verscheidene manieren\n"; print "- Zonder opties wordt het commando in interactieve modus gestart\n"; print " In deze modus kan u steeds help typen om een lijst te krijgen\n"; print " van de mogelijke commandos. Deze help beschrijft echter de \n"; print " commandline interface, die slechts 1 verwerking per oproep \n"; print " zal verwerken.\n"; print "- Met de hier beschreven opties zal het programma 1 actie \n"; print " ondernemen per oproep, dit systeem is handiger voor integratie\n"; print " in andere programmas.\n"; tussenRegel; print "-h\n"; print " Toont de help\n"; print " \@alias: help\n"; print "-p\n"; print " Drukt al de records in de databse af.\n"; print "-p [ [ [..]]]"; print " Drukt records met nummers af (in de gegeven volgorde).\n"; print "-b []\n"; print " Start de browser met het gegeven record centraal.\n"; print " \@alias: browse\n"; print " \@alias: browser\n"; print "-a :: ::::\n"; print " Voegt een nieuw record in met de gegeven data als waarden.\n"; print " eg: -a Steward\\ John::London\\ Avenue\\ 6::3748\\ Paris::France\n"; print " \@alias: add \n"; print " \@alias: voeg toe\n"; print " \@alias: voegtoe\n"; print "-u [naam ][straat ][nr ]\n"; print " [stad ][land ]\n"; print " Vervangt in de opgegeven data, door de nieuwe gegevens.\n"; print " De volgorde van de ingegeven gevens maakt niet uit.\n"; print " \@alias: update [naam ... \n"; print " \@alias: wijzig [naam ... \n"; print "-s :: ::::\n"; print " Vervangt het record in met het record omschreven door de\n"; print " ingegeven data (die na staat)\n"; print " \@alias: subs\n"; print " \@alias: substute\n"; print " \@alias: verv\n"; print " \@alias: vervang\n"; print "-d \n"; print " Haalt een gebruiker uit de database.\n"; print " \@alias: del\n"; print " \@alias: delete\n"; print " \@alias: verwijder\n"; print "-r \n"; print " Berekent de weg tussen adres en adres \n"; print " en drukt hier een leesbare beschrijving van af\n"; print " \@alias: -w\n"; print " \@alias: route \n"; print " \@alias: weg\n"; tussenRegel; } #- De door de gebruiker ingevoerde data wordt hier een eerste maal #-- geparsed zodat hij naar de juiste functies doorgezonden #-- kan worden. if(!exists($ARGV[0])) { interactieveModus; } elsif($ARGV[0] eq '-h' || $ARGV[0] eq 'help') { cliHelp; } else { cliModus @ARGV; }