NAME
App::Rssfilter::Rule - match and filter RSS feeds
VERSION
version 0.07
SYNOPSIS
use App::RssFilter::Rule;
use Mojo::DOM;
my $rss = Mojo::DOM->new( 'an RSS document' );
my $delete_duplicates_rule = App::Rssfilter::Rule->new( Duplicate => 'DeleteItem' );
# shorthand for
$delete_duplicates_rule = App::Rssfilter::Rule->new(
condition => 'App::Rssfilter::Match::Duplicate',
action => 'App::Rssfilter::Filter::DeleteItem',
);
# apply rule to RSS document
$delete_duplicates_rule->constrain( $rss );
# write modules with match and filter subs
package MyMatcher::LevelOfInterest;
sub new {
my ( $class, @bracketed_args) = @_;
if ( grep { $_ eq 'BORING' } @bracketed_args ) {
# turn on boredom detection circuits
...
}
...
}
sub match {
my ( $self, $mojo_dom_rss_item ) = @_;
...
}
package MyFilter::MakeMoreInteresting;
sub filter {
my ( $reason_for_match,
$matched_mojo_dom_rss_item,
@bracketed_args ) = @_;
...
}
package main;
my $boring_made_interesting_rule = App::Rssfilter::Rule->new(
'MyMatcher::LevelOfInterest[BORING]'
=> 'MyFilter::MakeMoreInteresting[glitter,lasers]'
);
$boring_made_interesting_rule->constrain( $rss );
my $interesting_with_decoration_rule = App::Rssfilter::Rule->new(
condition => MyMatcher::LevelOfInterest->new('OUT_OF_SIGHT'),
condition_name => 'ReallyInteresting', # instead of plain 'MyMatcher::LevelOfInterest'
action => 'MyFilter::MakeMoreInteresting[ascii_art]',
);
$interesting_with_decoration_rule->constrain( $rss );
# or use anonymous subs
my $space_the_final_frontier_rule = App::Rssfilter:Rule->new(
condition => sub {
my ( $item_to_match ) = @_;
return $item_to_match->title->text =~ / \b space \b /ixms;
},
action => sub {
my ( $reason_for_match, $matched_item ) = @_;
my @to_check = ( $matched_item->tree );
my %seen;
while( my $elem = pop @to_check ) {
next if 'ARRAY' ne ref $elem or $seen{ $elem }++;
if( $elem->[0] eq 'text' ) {
$elem->[1] =~ s/ \b space \b /\& (the final frontier)/xmsig;
}
else
{
push @to_check, @{ $elem };
}
}
},
);
$space_the_final_frontier_rule->constrain( $rss );
### or with an App::Rssfilter feed or group
use App::RssFilter::Feed;
my $feed = App::RssFilter::Feed->new( 'examples' => 'http://example.org/e.g.rss' );
$feed->add_rule( 'My::Matcher' => 'My::Filter' );
# same as
$feed->add_rule( App::Rssfilter::Rule->new( 'My::Matcher' => 'My::Filter' ) );
$feed->update;
DESCRIPTION
This module will test all item elements in a Mojo::DOM object against a condition, and apply an action on items where the condition is true.
It consumes the App::Rssfilter::Logger role.
ATTRIBUTES
logger
This is a object used for logging; it defaults to a Log::Any object. It is provided by the App::Rssfilter::Logger role.
condition
This is the module, object, or coderef to use to match item elements for filtering. Modules are passed as strings, and must contain a match sub. Object must have a match method.
_match
This is a coderef created from this rule's condition which will be used by "match" to check RSS items. It is automatically coerced from the condition attribute and cannot be passed to the constructor.
If this rule's condition is an object, _match will store a wrapper which calls the match method of the object. If this rule's condition is a subref, _match will store the same subref.
If this rule's condition is a string, it is treated as a namespace. If the string is not a fully-specified namespace, it will be changed to App::Rssfilter::Match::<string>; if you really want to use &TopLevelNamespace::match, specify condition as '::TopLevelNamespace' (or directly as \&TopLevelNameSpace::match). Additional arguments can be passed to the matcher by appending then to the string, separated by commas, surrounded by square brackets.
_match will then be set to a wrapper:
If
<namespace>::newexists,_matchwill be set as ifconditionhad originally been the object returned from calling<namespace>::new( @additional_arguments ).Otherwise,
_matchwill store a wrapper which calls<namespace>::match( $rss_item, @additional_arguments ).
condition_name
This is a nice name for the condition, which will be used as the reason for the match given to the action. Defaults to the class of the condition, or its value if it is a simple scalar, or unnamed RSS matcher otherwise.
action
This is the module, object, or coderef to use to filter item elements matched by this rule's condition. Modules are passed as strings, and must contain a filter sub. Object must have a filter method.
_filter
This is a coderef created from this rule's action which will be used by "filter" to check RSS items. It is automatically coerced from the action attribute and cannot be passed to the constructor.
If this rule's action is an object, _filter will store a wrapper which calls the filter method of the object. If this rule's action is a subref, _filter will store the same subref.
If the rule's action is a string, it is treated as a namespace. If the string is not a fully-specified namespace, it will be changed to App::Rssfilter::filter::<string>; if you really want to use &TopLevelNamespace::filter, specify action as '::TopLevelNamespace' (or directly as \&TopLevelNameSpace::filter). Additional arguments can be passed to the filter by appending then to the string, separated by commas, surrounded by square brackets.
The filter will then be set to a wrapper:
If
<namespace>::newexists,_filterwill be set as ifactionhad originally been the object returned from calling<namespace>::new( @additional_arguments ).Otherwise,
_filterwill store a wrapper which calls<namespace>::filter( $rss_item, @additional_arguments ).
action_name
This is a nice name for the action. Defaults to the class of the action, or its value if it is a simple scalar, or unnamed RSS filter otherwise.
METHODS
match
my $did_match = $self->match( $item_element_from_Mojo_DOM );
Returns the result of testing this rule's condition against $item.
filter
$self->filter( $item_element_from_Mojo_DOM );
Applies this rule's action to $item.
constrain
my $count_of_filtered_items = $rule->constrain( $Mojo_DOM );
Gathers all child item elements of $Mojo_DOM for which the condition is true, and applies the action to each. Returns the number of items that were matched (and filtered).
SEE ALSO
AUTHOR
Daniel Holz <dgholz@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2013 by Daniel Holz.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.