summaryrefslogtreecommitdiffstats
path: root/scripts/duckduckgo.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/duckduckgo.pl')
-rw-r--r--scripts/duckduckgo.pl256
1 files changed, 256 insertions, 0 deletions
diff --git a/scripts/duckduckgo.pl b/scripts/duckduckgo.pl
new file mode 100644
index 0000000..cf45747
--- /dev/null
+++ b/scripts/duckduckgo.pl
@@ -0,0 +1,256 @@
+# duckduckgo.pl is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+use strict;
+use POSIX;
+use vars qw($VERSION %IRSSI);
+
+use Irssi;
+use LWP::UserAgent;
+use HTML::Entities;
+use URI::Escape;
+
+$VERSION = '0.03';
+%IRSSI = (
+ authors => 'bw1',
+ contact => 'bw1@aol.at',
+ name => 'duckduckgo',
+ description => 'search by https://duckduckgo.com/html/',
+ license => 'lgplv3',
+ url => 'http://scripts.irssi.org',
+ changed => '2021-10-09',
+ selfcheckcmd=> 'ddg -check',
+);
+
+my $url="https://duckduckgo.com/html?q={}";
+#my $url="https://duckduckgo.com/html?q=irssi";
+my $view_count=5;
+my $browser="firefox '{}'";
+
+my @res;
+my $res_next;
+
+# fork
+my $read_handle;
+my $write_handle;
+my $forkcount=0;
+my $pipe_tag;
+
+sub www_get {
+ (my $url) =@_;
+ # Initialize LWP
+ my $ua = new LWP::UserAgent;
+ $ua->agent("duckduckgo.pl/0.1 " . $ua->agent);
+ # get
+ my $req = new HTTP::Request GET =>$url;
+ my $res = $ua->request($req);
+ return $res->content;
+}
+
+sub content2res {
+ (my $content) = @_;
+ my @content =split /\n/,$content;
+ my @res;
+ my $index=1;
+ foreach (@content) {
+ if ($_ =~ m/class="result__a"/) {
+ my %r;
+ $r{index}=$index;
+ # url
+ $_ =~ m/href="(.*?)"/;
+ $1 =~ m/uddg=(.*)&amp/;
+ my $u=uri_unescape($1);
+ $r{url}=$u;
+ # txt
+ $_ =~ m#">(.*?)</a>#;
+ my $s =$1;
+ $r{txt_raw}=$s;
+ $s=~s/<b>/%U/g;
+ $s=~s#</b>#%U#g;
+ $r{txt}=$s;
+ # out
+ push @res,{%r};
+ $index++;
+ }
+ }
+ return @res;
+}
+
+sub backgroundf {
+ (my $url, my $write_handle) =@_;
+ print "child start";
+ my $res = www_get($url);
+ print "child fertig";
+ print $write_handle $res;
+ print $write_handle "\n";
+ close $write_handle;
+}
+
+sub view_results {
+ my ($start) =@_;
+ print "duckduckgo: results ";
+ for (my $c=$start; $c < $view_count+$start && $c <= $#res; $c ++) {
+ print $c,". ",$res[$c]->{txt};
+ if (length($res[$c]->{url}) <50) {
+ print " ",$res[$c]->{url};
+ } else {
+ print " ",substr($res[$c]->{url},0,20),"=>>";
+ }
+ }
+}
+
+sub sig_result {
+ print "sig_result";
+ my $r;
+ my $o_fh;
+ # input
+ $o_fh=select($read_handle);
+ local $/;
+ select($o_fh);
+ $r=readline($read_handle);
+ close($read_handle);
+ Irssi::input_remove($pipe_tag);
+ # filter
+ @res= content2res($r);
+ $res_next=0;
+ $forkcount--;
+ view_results($res_next);
+}
+
+sub sig_config {
+ $url = Irssi::settings_get_str('ddg_url');
+ $view_count = Irssi::settings_get_int('ddg_view_count');
+}
+
+sub cmd_ddg {
+ my ($args, $server, $witem) = @_;
+
+ my @alist =split / /,$args;
+ if ($alist[0] !~ m/^-/) {
+ cmd_searchf($args);
+ } else {
+ if ($alist[0] eq '-browser') {
+ cmd_browser($alist[1]);
+ } elsif ($alist[0] eq '-next') {
+ cmd_next();
+ } elsif ($alist[0] eq '-help') {
+ cmd_help('ddg');
+ } elsif ($alist[0] eq '-drop') {
+ cmd_drop($alist[1],$witem);
+ } elsif ($alist[0] eq '-check') {
+ @res=();
+ cmd_searchf("irssi");
+ Irssi::timeout_add_once(3000,\&self_check,'');
+ }
+ }
+}
+
+sub cmd_drop {
+ my ($args, $witem) =@_;
+ if ($witem) {
+ $witem->command("/say $res[$args*1]->{url}");
+ }
+}
+
+sub cmd_next {
+ $res_next+=$view_count;
+ view_results($res_next);
+}
+
+sub cmd_searchf {
+ my ($args) = @_;
+ my $url2=$url;
+ $args=~s/ /+/g;
+ $url2=~s/{}/$args/;
+ # fork
+ if ($forkcount==0) {
+ print "ddg:",$url2;
+ $forkcount++;
+ pipe($read_handle, $write_handle);
+ my $o_fh=select($write_handle);
+ local $|=1;
+ select($o_fh);
+ my $pid =fork();
+ if (not defined $pid) {
+ _error("Can't fork: Aborting");
+ close($read_handle);
+ close($write_handle);
+ return;
+ }
+ if ($pid == 0) {
+ # child
+ backgroundf($url2,$write_handle);
+ POSIX::_exit(1);
+ } else {
+ # parent
+ close ($write_handle);
+ Irssi::pidwait_add($pid);
+ $pipe_tag = Irssi::input_add(fileno($read_handle),
+ Irssi::INPUT_READ, \&sig_result, "");
+ }
+ }
+}
+
+sub cmd_browser {
+ my ($args) = @_;
+ my $b=$browser;
+ $b =~ s/{}/$res[$args*1]->{url}/;
+ system($b);
+}
+
+sub self_check {
+ my $s='ok';
+ Irssi::print("Result count: ".scalar(@res));
+ Irssi::print("Result url: ".$res[0]->{url});
+ Irssi::print("Result txt length: ".length($res[0]->{txt}));
+ if ( scalar ( @res ) <10 ) {
+ $s= "Error: result count (".scalar(@res).")";
+ } elsif ( $res[0]->{url} !~ m/^http.*\/$/ ) {
+ $s= "Error: url (".$res[0]->{url}.")";
+ } elsif ( length($res[0]->{txt}) < 5 ) {
+ $s= "Error: txt length (".length($res[0]->{txt}).")";
+ }
+ Irssi::print("Selfcheck $s");
+ my $schs = exists $Irssi::Script::{'selfcheckhelperscript::'};
+ Irssi::command("selfcheckhelperscript $s") if ( $schs );
+}
+
+sub cmd_help {
+ if ($_[0] eq 'ddg' || $_[0] eq 'duckduckgo') {
+
+my $help = <<'END';
+/ddg <keywords> search for the keywords
+/ddg -next display the next results
+/ddg -browser <num> give the url to firefox
+/ddg -drop <num> drop the url in a channel
+/ddg -check self check
+
+settings:
+ ddg_view_count,
+ ddg_url, ddg_browser (placeholder {} )
+END
+ Irssi::print($help, MSGLEVEL_CLIENTCRAP);
+ Irssi::signal_stop;
+ }
+}
+
+Irssi::settings_add_str("duckduckgo", "ddg_url", $url);
+Irssi::settings_add_str("duckduckgo", "ddg_browser", $browser);
+Irssi::settings_add_int("duckduckgo", "ddg_view_count", $view_count);
+
+Irssi::signal_add('setup changed', "sig_config");
+
+Irssi::command_bind('help',\&cmd_help);
+Irssi::command_bind("ddg", \&cmd_ddg);
+Irssi::command_set_options('ddg','help browser next drop');
+
+sig_config();