package Bucky::Poetaster; use Digest::MD5; use Rest; # Maximum distance to indent a line of text my $MAX_INDENT = 3; # Maximum number of words per line my $MAX_WORD_COUNT = 6; # Maximum number of letters per line my $MAX_CHAR_COUNT = 36; # Number of spaces to print per level of indentation my $INDENT_WIDTH = 2; sub new { my ($class, $self) = @_; $self ||= {}; $self->{'indent'} = 0; bless $self, $class; return $self; } # Given a big block of text, reformat it to resemble a poem sub poem { my ($self, $text) = @_; # Split the text into words my @words = split / /, $text; # Initialize all counters to zero $self->{'indent'} = 0; my $word_count = 0; my $char_count = 0; # variable to dump all data onto my $stanza = ''; # loop over all words in the block foreach my $word (@words) { # if word is undefined, skip it (two spaces next to each other) next unless $word; # if word starts with non-alphanumeric character # make a new line and then print the word if ($word =~ /^[^a-z0-9<>]/i) { $word_count = 1; $char_count = length $word; $stanza .= $self->indent; $stanza .= $word; next; } # if word ends with non-alphanumeric character, # print the word and THEN start a new line if ($word =~ /([^a-z<>])$/i) { my $punct = $1; # if the word ends with a period, start a new stanza if ($punct eq "." || $punct eq "?") { $self->{'indent'} = 0; } $word_count = 0; $char_count = 0; $stanza .= " " . $word; $stanza .= $self->indent; next; } # otherwise, print the word $stanza .= " ". $word; # tally the line length and number of words on the line $word_count += 1; $char_count += length($word)+ 1; # if we've printed a whole line's worth, start a new line if ($char_count > $MAX_CHAR_COUNT || $word_count > $MAX_WORD_COUNT) { $stanza .= $self->indent; $word_count = 0; $char_count = 0; } } # return the new poem cuz we're done return $stanza; } # Modify the current indentation depth, # and return a string constituting the indent sub indent { my ($self) = @_; # if we've already indented as far as we'd like, pull back if ($self->{'indent'} > $MAX_INDENT) { $self->{'indent'} -= 1; } # otherwise, indent one notch further else { $self->{'indent'} += 1; } # print a newline, then indent according to the indentation width return "\n" . " " x ( $self->{'indent'} * $INDENT_WIDTH ); } sub url_cache { my ($self, $url) = @_; my $hash = md5_hex($url); my $path = $self->url_cache_path($hash); while (-e $path) { open P, $path or last; my @lines =
; close P; return join "", @lines; } my $data = Rest->new->rest_get_raw($url); open P, ">$path" or return $data; print P $data; close $p; return $data; } sub url_cache_path { my ($self, $hash) = @_; my $path = $self->bucky_data_path . "/poetaster/" . $hash; return $path; } sub log { my ($self, $date) = @_; my $criteria = {}; $criteria->{'date'} = $date if $date; return $self->db->select("poetaster_log", $criteria); } sub log_query { my ($self, $query, $total) = @_; return unless $query; my $date = time; $matches ||= '0'; $self->db->insert("poetaster_log", { query => $query, date => $date, matches => $total }); } 1;