Rückwärtssuche bei dasoertliche.de

pbx-stefan

Neuer User
Mitglied seit
26 Jan 2006
Beiträge
128
Punkte für Reaktionen
0
Punkte
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` (
  `lfdnr` int(11) NOT NULL auto_increment,
  `name` varchar(40) collate latin1_general_ci NOT NULL default '',
  `msisdn` varchar(15) collate latin1_general_ci NOT NULL default '',
  `description` varchar(50) collate latin1_general_ci NOT NULL default '',
  `email` varchar(30) collate latin1_general_ci NOT NULL default '',
  `anzahl` int(11) NOT 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{name} eq "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
 

HobbyStern

Aktives Mitglied
Mitglied seit
5 Dez 2005
Beiträge
1,837
Punkte für Reaktionen
0
Punkte
36
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
 

pbx-stefan

Neuer User
Mitglied seit
26 Jan 2006
Beiträge
128
Punkte für Reaktionen
0
Punkte
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
 

3CX PBX - GRATIS
Linux / Win / Cloud

Statistik des Forums

Themen
233,171
Beiträge
2,030,947
Mitglieder
351,576
Neuestes Mitglied
ssattes