App-DuckPAN

 view release on metacpan or  search on metacpan

lib/App/DuckPAN/Cmd/Server.pm  view on Meta::CPAN


	$self->app->emit_info("Starting up webserver...", "You can stop the webserver with Ctrl-C");

	require App::DuckPAN::Web;

	my $web    = App::DuckPAN::Web->new(%web_args);
	my $runner = Plack::Runner->new(
		#loader => 'Restarter',
		includes => ['lib'],
		app      => sub { $web->run_psgi($self->app, @_) },
	);
	#$runner->loader->watch("./lib");
	$runner->parse_options("--port", $self->port);
	exit $runner->run;
}

sub slurp_or_empty {
	my ($self, $which) = @_;
	my $cache_path = $self->asset_cache_path;
	my $contents = '';
	foreach my $which_file (grep { $_->{internal} } (@$which)) {
		my $where = $which_file->{internal};
		my $change_method = ($where =~ m/\.js$/) ? 'change_js' : ($where =~ m/\.css$/) ? 'change_css' : 'change_html';

		$contents .= $self->make_source_comment($which_file) . $self->$change_method($where->slurp) if ($where->exists);
	}

	return $contents;
}

sub make_source_comment {
	my ($self, $file_info) = @_;

	my $comment  = '';
	my $internal = $file_info->{internal};
	my $title    = $file_info->{name} || $internal;
	if ($internal =~ /js$/) {
		$comment = '// ' . $title;
	}
	elsif ($internal =~ /css$/) {
		$comment = '/* ' . $title . '*/';
	}
	elsif ($internal =~ /html$/) {
		$comment = '<!-- ' . $title . ' -->';
	}

	return "\n$comment\n";    # Just two blank lines if we don't know how to comment for the file type.
}

# Force DuckPAN to ignore requests for certain files
# that are not needed (ie. d.js, s.js, g.js, post2.html)
sub change_js {
	my ( $self, $js ) = @_;
	$js =~ s!/([dsg]\d+?|duckduck|duckgo_dev)\.js\?!/?duckduckhack_ignore=1&!g;
	$js =~ s!/post2\.html!/?duckduckhack_ignore=1&!g;
	return $self->change_css($js);
}

# Rewrite all relative asset links in CSS
# Capture leading quote, insert $hostname, append filename
# E.g url("/assets/background.png") => url("http://duckduckgo.com/assets/background.png")
sub change_css {
	my ( $self, $css ) = @_;
	my $hostname = $self->hostname;
	$css =~ s!:\s*url\((["'])?/!:url\($1http://$hostname/!g;
	return $css;
}

sub change_html {
	my ( $self, $html ) = @_;

	my $root = HTML::TreeBuilder->new;
	$root->parse($html);

	my @a = $root->look_down(
		"_tag", "a"
	);

	my @link = $root->look_down(
		"_tag", "link"
	);

	# Make sure DuckPAN serves DDG CSS (already pulled down at startup)
	# ie <link href="/s123.css"> becomes <link href="/?duckduckhack_css=1">
	# Also rewrite relative links to hostname
	my $has_css = 0;
	for (@a, @link) {
		if ($_->attr('type') && $_->attr('type') eq 'text/css') {
			# We only want to load the CSS file once.
			# We only load it once because /?duckduckhack_css=1 already has all of the CSS
			# in a single page.
			unless($has_css) {
				$_->attr('href','/?duckduckhack_css=1');
				$has_css = 1;
			}
			else {
				$_->attr('href','/?duckduckhack_ignore=1');
			}
		}
		elsif (defined $_->attr('href') && substr($_->attr('href'),0,1) eq '/') {
			$_->attr('href','http://'.$self->hostname.''.$_->attr('href'));
		}
	}

	my @script = $root->look_down(
		"_tag", "script"
	);

	# Make sure DuckPAN serves DDG JS (already pulled down at startup)
	# ie <link href="/d123.js"> becomes <link href="/?duckduckhack_js=1">
	# Also rewrite relative links to hostname

	# Temp Fix: Force ignore of d.js & duckduck.
	# This logic needs to be improved!

	my $has_ddh = 0;
	for (@script) {
		if (my $src = $_->attr('src')) {
			next if ($src =~ m/^\/\?duckduckhack_/); # Already updated, no need to do again
			if ($src =~ m/^\/(dpan\d+|duckpan)\.js/) {
				if ($has_ddh){



( run in 2.418 seconds using v1.01-cache-2.11-cpan-d8267643d1d )