Updated 4chan thread downloader

This is updated for the version of AXCEL which was uploaded on 11/12/2011. Compiled windows binary included.
Download: http://www.mediafire.com/?jyjjq712nqp5l2f

Code:

#include "axcel/axcel.h"
use fs;
use net;

struct fcpost {
	string author;
	string img;
	long double size;
	ulong height;
	ulong width;
};

int main(int argc, char** argv) {
	unless (argc > 1)
		die (
			"4chan Thread Downloader by Jakash3\n"
			"Download all images from a thread\n"
			"Usage: %s THREAD_URL [-o dir] [-s max] [-d height width] "
			"[-a author]\n\n"
			"-o dir            Output directory\n"
			"-s max            Maximum size in kilobytes\n"
			"-d height width   Maximum height and width\n"
			"-a author         Only download images from this author\n",
			argv[0]
		);
	
	fcpost post;
	socket::tcp sock;
	http::header head;
	http::response response;
	string s = argv[1], t, u;
	file f;
	ulong i, j, k;
	data d;
	
	long double max = 0;
	ulong height = 0, width = 0;
	string author;

	for (i = 2; i < argc; i++) {
		if (eq(argv[i], "-o")) cd(argv[++i]);
		else if (eq(argv[i], "-s")) max = stof<long double>(argv[++i]);
		else if (eq(argv[i], "-a")) author = argv[++i];
		else if (eq(argv[i], "-d")) {
			height = stoi<ulong>(argv[++i]);
			width = stoi<ulong>(argv[++i]);
		}
	}
	s = s.munch("http://").burn('#');
	unless (sock.connect(s.burn('/'), "80")) {
		con.put("Failed to connect: ").echo(sock.error());
		return 1;
	}
	sock <<
		"GET /" << s.slurp('/') << " HTTP/1.1\r\n"
		"Host: " << s.burn('/') << "\r\n\r\n";
	response = sock.drink("\r\n");
	head = sock.drink("\r\n\r\n");

	con.put(response);
	if (response.code != 200) { sock.close(); return 1; }
	s = sock.drink("</html>");
	sock.close();

	for (s.rewind(), t = s.gets(); !t.ends("</html>"); t = s.gets()) {
		if (t.str("<a href=\"http://images.4chan.org") == -1) continue;

		post.author = t.slurp("<span class=\"commentpostername\">").burn('<');
		post.img = t.slurp("<span class=\"filesize\">").slurp("<a href=\"").burn('\"');
		u = t.slurp("<span class=\"filesize\">").slurp("-(");
		if (u.slurp(' ').starts("KB")) post.size = stof<long double>(u.burn(' '));
		else if (u.slurp(' ').starts("MB")) post.size = stof<long double>(u.burn(' ')) * 1024;
		else post.size = 0;
		post.height = atoi(u.slurp(", "));
		post.width = atoi(u.slurp('x'));
		
		if (max) if (post.size > max) continue;
		if (height) if (post.height > height) continue;
		if (width) if (post.width > width) continue;
		unless (author.empty()) if (post.author != author) continue;
		
		unless (f.open(post.img.rslurp('/'), "wb")) {
			con <<
				"Error opening " << post.img.rslurp('/') << " for writing: " <<
				f.error() << "\n";
			return 1;
		}
		sock = socket::tcp();
		unless (sock.connect("images.4chan.org", "80")) {
			con << "Error connecting to images.4chan.org: " << sock.error() << "\n";
			return 1;
		}

		u.clear();
		con.put(post.img);
		sock <<
			"GET " << post.img.slurp(".org") << " HTTP/1.1\r\n"
			"Host: images.4chan.org\r\n\r\n";
		response = sock.drink("\r\n");
		if (response.code != 200) con.echo(" FAILED");
		else con.echo();
		head = sock.drink("\r\n\r\n");
		j = atoi((string)head["Content-Length"].var());
		con << "Downloaded 0 / " << j / 1024 << " KB";
		for (i = 0, k = 1024; i < j; i++) {
			f.putc(sock.getc());
			if (i == k) {
				con.putcr();
				con << "Downloaded " << i / 1024 <<
				"/" << j / 1024 << " KB";
				k += 1024;
			}
		}
		con.echo();
		con.echo();
		f.close();
		sock.close();
	}
	return 0;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: