#!/usr/bin/perl # Joe Gillotti - 11/3/2011 - GPL # # Multithreaded 4chan image downloader... # Run from CLI, pass URL to a 4hcan thread, and it'll # store all the images in the thread to a folder of the thread ID # in the current directory and check back every two seconds, # while waiting for existing downloads to finish. # # Pass it 'silent' right after the URL to make it not output anything, # perfect for running it with & # # Cool, no? use strict; use warnings; use threads; use Cwd; my $url = shift || die "Pass me a chan url..\n"; my $silent = shift; $silent = defined($silent) && $silent eq 'silent' ? 1 : 0; my $thread; unless ($url =~ m/\/(\d+)$/) { die "I need a 4chan thread\n"; } $thread = $1; my $image_store = getcwd()."/$thread/"; unless (-d $image_store) { mkdir $image_store; } my $filename; my @downThreads; my $saved_images = 0; my $skipped; my $save_res; my %images; while (1) { $skipped = 0; my $contents = `wget -q -O - $url`; if ($contents =~ m/4chan \- 404/ || $contents eq '') { if ($silent) { exit(0); } else { die "Thread 404'd/died... We saved $saved_images images from it.\n"; } } %images = map{$_ => 1} ($contents =~ m/http:\/\/images\.4chan\.org\/[a-z]+\/src\/\d+\.(?:jpeg|jpg|png|gif)/g); if (scalar keys %images == 0) { if ($silent) { exit(1); } else { die "No images in thread\n"; } } foreach (keys %images) { $filename = m/(([^\/]+))$/ ? $1 : 0; next unless $1; unless (-e "$image_store$filename") { push @downThreads, threads->create(sub { my ($url, $path, $silent) = @_; print "Saving $url to $path...\n" unless $silent; `wget -q "$url" -O "$path"`; return { file => $path, success => -e $path ? 1 : 0 }; }, $_, $image_store.$filename, $silent); } else { $skipped++; } } if (scalar @downThreads) { print "Waiting for ".scalar @downThreads." download threads to finish before refreshing again...\n" unless $silent; while ($_ = pop @downThreads) { $save_res = $_->join(); $saved_images += $save_res->{success}; print $save_res->{file}." saved ".($save_res->{success} ? 'successfully' : 'unsuccessfully')."\n" unless $silent; } } else { print "Nothing new with this pass..skipping $skipped saved images..\n" unless $silent; } print "Waiting two seconds for next thread refresh..\n" unless $silent; sleep 2; }