BusyBird
view release on metacpan or search on metacpan
lib/BusyBird/Main/PSGI/View.pm view on Meta::CPAN
return _html_link($text, href => $url, target => "_blank");
}
sub _make_path {
my ($script_name, $given_path) = @_;
if(substr($given_path, 0, 1) eq "/") {
return "$script_name$given_path";
}else {
return $given_path;
}
}
sub template_functions {
my $script_name = $_[0]->{script_name};
return {
js => \&JavaScript::Value::Escape::js,
link => html_builder(\&_html_link),
image => html_builder {
my (@attr) = @_;
return try {
my $attr_str = _html_attributes_string(['src'], @attr);
return qq{<img $attr_str />}
}catch {
return "";
};
},
bb_level => sub {
my $level = shift;
$level = 0 if not defined $level;
return $level;
},
path => sub { _make_path($script_name, $_[0]) },
script_name => sub { $script_name },
};
}
sub _render_text_segment {
my ($self, $timeline_name, $segment, $status) = @_;
return undef if !defined($segment->{entity}) || !defined($segment->{type});
my $url_builder = $self->{main_obj}->get_timeline_config($timeline_name, "$segment->{type}_entity_url_builder");
my $text_builder = $self->{main_obj}->get_timeline_config($timeline_name, "$segment->{type}_entity_text_builder");
return undef if !defined($url_builder) || !defined($text_builder);
my $url_str = $url_builder->($segment->{text}, $segment->{entity}, $status);
return undef if !_is_valid_link_url($url_str);
my $text_str = $text_builder->($segment->{text}, $segment->{entity}, $status);
$text_str = "" if not defined $text_str;
return _html_link_status_text($text_str, $url_str);
}
sub template_functions_for_timeline {
my ($self, $timeline_name) = @_;
weaken $self; ## in case the functions are kept by $self
return {
bb_timestamp => sub {
my ($timestamp_string) = @_;
return "" if !$timestamp_string;
my $timezone = $self->_get_timezone($self->{main_obj}->get_timeline_config($timeline_name, "time_zone"));
my $dt = BusyBird::DateTime::Format->parse_datetime($timestamp_string);
return "" if !defined($dt);
$dt->set_time_zone($timezone);
$dt->set_locale($self->{main_obj}->get_timeline_config($timeline_name, "time_locale"));
return $dt->strftime($self->{main_obj}->get_timeline_config($timeline_name, "time_format"));
},
bb_status_permalink => sub {
my ($status) = @_;
my $builder = $self->{main_obj}->get_timeline_config($timeline_name, "status_permalink_builder");
my $url = try {
$builder->($status);
}catch {
my ($e) = @_;
bblog("error", "Error in status_permalink_builder: $e");
undef;
};
return (_is_valid_link_url($url) ? $url : "");
},
bb_text => html_builder {
my $status = shift;
return "" if not defined $status->{text};
my $segments_ref = split_with_entities($status->{text}, $status->{entities});
my $result_text = "";
foreach my $segment (@$segments_ref) {
my $rendered_text = try {
$self->_render_text_segment($timeline_name, $segment, $status)
}catch {
my ($e) = @_;
bblog("error", "Error while rendering text: $e");
undef;
};
$result_text .= defined($rendered_text) ? $rendered_text : _escape_and_linkify_status_text($segment->{text});
}
return $result_text;
},
bb_attached_image_urls => sub {
my ($status) = @_;
my $urls_builder = $self->{main_obj}->get_timeline_config($timeline_name, "attached_image_urls_builder");
my @image_urls = try {
$urls_builder->($status);
}catch {
my ($e) = @_;
bblog("error", "Error in attached_image_urls_builder: $e");
();
};
return [grep { _is_valid_link_url($_) } @image_urls ];
},
};
}
{
my $timezone_cache = Cache::Memory::Simple->new();
my $CACHE_EXPIRATION_TIME = 3600 * 24;
my $CACHE_SIZE_LIMIT = 100;
sub _get_timezone {
my ($self, $timezone_string) = @_;
if($timezone_cache->count > $CACHE_SIZE_LIMIT) {
$timezone_cache->purge();
if($timezone_cache->count > $CACHE_SIZE_LIMIT) {
$timezone_cache->delete_all();
}
}
return $timezone_cache->get_or_set($timezone_string, sub {
return DateTime::TimeZone->new(name => $timezone_string),
( run in 0.515 second using v1.01-cache-2.11-cpan-ceb78f64989 )