.titleBar { margin-bottom: 5px!important; }

Rückwärtssuche bei dasoertliche.de

Dieses Thema im Forum "Asterisk Skripte" wurde erstellt von pbx-stefan, 23 Nov. 2006.

  1. pbx-stefan

    pbx-stefan Neuer User

    Registriert seit:
    26 Jan. 2006
    Beiträge:
    128
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Hallo zusammen,

    nachdem ich bei mir kein AGI Shell Script läuft (warum auch immer...), habe ich das mal in Perl gebaut.

    Zusätlich cached das Script die 'Erfahrungen' in einer MySQL DB.
    Dort werden die nicht bei dasoertliche.de zu zu findenen Einträge ebenfalls gespeichert. Wer mag, kann die Daten dort manuell vervollständigen oder anpassen, damit in Zukunft eine Anzeige möglich ist.

    Voraussetzung ist eine Box mit Asterisk, MySQL und Perl. In Perl soll DBI und LWP verfügbar sein.

    Meine DB nennt sich 'phonemail'. Mal schauen, irgendwie werde ich das weiter entwickeln.
    Meine eine Tabelle wird so erstellt:
    PHP:
    #
    # Tabellenstruktur für Tabelle `contacts`
    #

    CREATE TABLE `contacts` (
      `
    lfdnrint(11NOT NULL auto_increment,
      `
    namevarchar(40collate latin1_general_ci NOT NULL default '',
      `
    msisdnvarchar(15collate latin1_general_ci NOT NULL default '',
      `
    descriptionvarchar(50collate latin1_general_ci NOT NULL default '',
      `
    emailvarchar(30collate latin1_general_ci NOT NULL default '',
      `
    anzahlint(11NOT NULL default '0',
      
    PRIMARY KEY  (`lfdnr`)
    ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=28 ;
    Natulich habe ich einen user, der darauf zugreifen darf.

    Mein 'reverse.stefan.agi' sieht so aus:
    PHP:
    #!/usr/bin/perl
    use DBI;
    use 
    LWP::Simple;

    $|=
    1;

    $anzahl=0;

    while(<
    STDIN>) {
        
    chomp;
        
    last unless length($_);
        if (/^
    agi_(\w+)\:\s+(.*)$/) {
            
    $AGI{$1} = $2;
        }
    }

    foreach 
    my $i (sort keys %AGI) {
        if (
    $i="callerid"){
            
    $MyCALLERID=$AGI{$i};
        }
    }


    #Cache DB öffnen
    my $dbh DBI->connect'dbi:mysql:phonemail''user''passwort') ||die "Kann keine Verbindung zum MySQL-Server aufbauen: $DBI::errstr\n";
    #

    #User aus contacts DB lesen
    my $contact $dbh->prepare"SELECT * from contacts where msisdn = $MyCALLERID limit 1;" ) || die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
    $contact->execute || die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";

    #ist da was?
    while ( my $result $contact->fetchrow_hashref() ) {
            foreach 
    my $name (keys %$result) {
                
    $contactdata{$name}=$result->{$name};
            }
            print 
    STDERR "Anrufer in DB gefunden: $contactdata{name}\n";
            
    $anzahl=$contactdata{anzahl};
            print 
    STDERR "Anzahl: $anzahl\n";
            
    $MyCALLERNAME=$contactdata{name};
    }    

    # wenn da ein Eintrag ist, dieser aber 'unbekannt' heisst zähle ich den Anruf hoch.
    # dann kann ich alle, Oftanrufer bevorzugt nachpflegen
    if ($contactdata{name} and $contactdata{nameeq "unbekannt"){
        
    $anzahl++;
        
    my $contact $dbh->prepare"UPDATE contacts set anzahl=$anzahl where msisdn = $MyCALLERID;" ) || die "Kann Stop Statement nicht vorbereiten: $DBI::errstr\n"
        
    $contact->execute || die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
        print 
    STDERR "Anrufer immer noch unbekannt ($anzahl)\n";
        
    # dem Namen füge ich die Häufigkeit hinzu, dann muss ic nicht immer in die DB
        
    $MyCALLERNAME="unbekannt ($anzahl)";
    }

    #wenn nun noch kein Datensatz d ist, gehe ich ins Internet
    if (!$contactdata{name}){
        
    $url 'http://www.dasoertliche.de/Controller?form_name=search_inv&ph='.$MyCALLERID;
        print 
    STDERR "$url\n";
        
    $document get($url);
        
    unless (defined $document) { 
            print 
    STDERR "ERROR, keine Antwort\n"
        };

        
    #haben die nichts für mich, schreibe ich das in die DB
        
    if ($document =~ /Kein Teilnehmer gefunden/){
            print 
    STDERR "Kein Teilnehmer bei DasÖrtliche gefunden\n"
            
    my $contact $dbh->prepare"INSERT into contacts (msisdn, name, anzahl) values ('$MyCALLERID', 'unbekannt', '1');" ) || die "Kann Stop Statement nicht vorbereiten: $DBI::errstr\n"
            
    $contact->execute || die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
            print 
    STDERR "Anrufer unbekannt\n";
            
    $MyCALLERNAME="unbekannt (1)";
        }

        
    #haben die was, schreibe ich auch das in die DB
        #ich nehme hier an, dass der Name hinter dem ersten Vorkommen von 'entry">' kommt
        
    if ($document =~ /class="entry">(.+)<\/a>/){
            
    my $contact $dbh->prepare"INSERT into contacts (msisdn, name) values ('$MyCALLERID', '$1');" ) || die "Kann Stop Statement nicht vorbereiten: $DBI::errstr\n"
            
    $contact->execute || die "Kann Abfrage nicht ausfuehren: $DBI::errstr\n";
            print 
    STDERR "Anrufer bei DasÖrtliche gefunden: ".$1."\n"
            
    $MyCALLERNAME=$1;
        }
    }
    print 
    "SET VARIABLE LONGNAME \"$MyCALLERNAME\"";

    #weil ich Ordentlich bin:
    $dbh->disconnect();

    Aufrufen tu ich das aus geeigneter Stelle im Flow einer Extension:

    PHP:
    exten => 3133xx,n,AGI,reverse.pl.agi
    exten 
    => 3133xx,n,SetCIDName(${LONGNAME})
    So langsam befüllen meine Anrufer die DB :)


    Gruß Stefan
     
  2. HobbyStern

    HobbyStern Aktives Mitglied

    Registriert seit:
    5 Dez. 2005
    Beiträge:
    1,837
    Zustimmungen:
    0
    Punkte für Erfolge:
    36
    Beruf:
    vorhanden
    Ort:
    Ruhrgebiet
    Hallo Du,

    darf ich mal ganz bescheiden fragen ob Asterisk die Abfrage eigentlich parallel macht oder wartet er auf die Antwort vom Server ?

    Ich habe die Reverssuche gerade zum ersten Mal online genutzt und mir fiel die "Geschwindigkeit" auf :) Da hab ich an Dein Skript gedacht ..

    Grüsse, Stefan
     
  3. pbx-stefan

    pbx-stefan Neuer User

    Registriert seit:
    26 Jan. 2006
    Beiträge:
    128
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Warum bescheiden sein...

    Ja. Mein Script wartet. Im ungünstigsten Fall 60 Sekunden... blöd für den Anrufer.
    Wem das nicht passt, der nimmt sich nach der Intsallation von LWP::Sipmle die Datei 'Simple.pm' und editiert in dem folgenden Abschnitt
    PHP:
    sub _trivial_http_get
    {
       
    my($host$port$path) = @_;
       
    #print "HOST=$host, PORT=$port, PATH=$path\n";

       
    require IO::Socket;
       
    local($^W) = 0;
       
    my $sock IO::Socket::INET->new(PeerAddr => $host,
                                        
    PeerPort => $port,
                                        
    Proto    => 'tcp',
                                        
    Timeout  => 60) || return undef;
    ...
    den timeout entsprechend.

    Wer mag (oder LWP::Simple auf der Box für verschiedene Anwendungen mit verschiedenen notwendigen Timeouts verwenden muss), nimmt anstatt LWP::Simple den LWP::Useragent. Dort kann man beim Aufruf den timeout mitgeben. Allerdings ist der UA etwas behäbiger, weil mächtiger.
    Perl Frickler kennen weitere Möglichkeiten, auch LWP::Simple mehrfach vorzuhalten...

    Alternativ kann man das Script auch umbauen:
    1. Timeout in Simple.pm auf 1 Sekunde setzen.
    2. nach Ablauf der Sekunde ein neues Script mit längerem Timeout aufrufen (z.B. mit 10 Sekunden in Simple10.pm und per 'use LWP::Simple10' eingebunden), allerdings als Hintergrund Task (deinscript.pl &) Dieses wird dann in Ruhe auf die Antwort warten.

    Alle Anrufer die innerhalb der ersten Sekunde beantwortet wurden, werden angezeigt, die anderen halt erst beim 2. Anruf... wenn überhaupt im Telefonbuch vorhanden.

    Gruß Stefan