summaryrefslogtreecommitdiff
path: root/bucky2/lib/Poetaster.pm
blob: da5b854eac8bd3d52e8ccc9c2115f5716985b169 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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 = <P>;
		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;