1# $Revision: 1.2 $ 2# $Id: Article.pm,v 1.2 2002/07/22 08:35:43 afoxson Exp $ 3 4# Mail::Freshmeat::Article - parses articles from freshmeat daily newsletters 5# Copyright (c) 2002 Adam J. Foxson. All rights reserved. 6 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16 17package Mail::Freshmeat::Article; 18 19use strict; 20use 5.005; 21use Carp; 22use vars qw($VERSION $AUTOLOAD); 23use Mail::Freshmeat::Utils; 24 25local $^W; 26 27($VERSION) = '$Revision: 1.2 $' =~ /\s+(\d+\.\d+)\s+/; 28 29sub new 30{ 31 my $type = shift; 32 my $entry = shift or croak "I need to be passed an entry."; 33 my $count = shift or croak "I need to be passed a count."; 34 my $class = ref($type) || $type; 35 my $self = bless {}, $class; 36 37 $self->{_attrs} = 38 [ 39 qw 40 ( 41 _title _posted_by_name _posted_by_url _posted_on _section 42 _description _url 43 ) 44 ]; 45 46 # these are the allowed entry accessors 47 $self->{_is_attr} = {map {$_ => 1} @{$self->{_attrs}}, '_full'}; 48 $self->_parse($entry, $count); 49 50 return $self; 51} 52 53sub article_keys 54{ 55 my $self = shift; 56 wantarray ? @{$self->{_attrs}} : $self->{_attrs}; 57} 58 59sub _parse 60{ 61 my $self = shift; 62 my $entry = shift or croak "I need to be passed an entry."; 63 my $count = shift or croak "I need to be passed a count."; 64 my @entries; 65 66 if ($entry =~ 67 m/ 68 ^ \s* (.*) $ \n 69 ^ \s* by \s (.*) \s \((.*)\) $ \n 70 ^ \s* Section: \s (.*) $ \n 71 ^ \s* (.*) $ \n 72 $_blank_line 73 (?s: (.+?) \n ) 74 $_blank_line 75 ^ \s* URL:\s (.*) $ 76 /mx) 77 { 78 $self->{_title} = $1; 79 $self->{_posted_by_name} = $2; 80 $self->{_posted_by_url} = $3; 81 $self->{_section} = $4; 82 $self->{_posted_on} = $5; 83 $self->{_description} = $6; 84 $self->{_url} = $7; 85 $self->{_full} = $entry; 86 } 87 else 88 { 89 _fatal_bug("Couldn't parse article $count (articles)."); 90 } 91 92 for my $key (keys %$self) 93 { 94 $self->{$key} = '' if not defined $self->{$key}; 95 } 96 97 return $self; 98} 99 100sub AUTOLOAD 101{ 102 my $self = $_[0]; 103 my ($package, $method) = ($AUTOLOAD =~ /(.*)::(.*)/); 104 105 return if $method =~ /^DESTROY$/; 106 unless ($self->{_is_attr}->{"_$method"}) 107 { 108 croak "No such article accessor entry: $method; aborting"; 109 } 110 111 my $code = q 112 { 113 sub 114 { 115 my $self = shift; 116 return $self->{_METHOD}; 117 } 118 }; 119 120 $code =~ s/METHOD/$method/g; 121 122 { 123 no strict 'refs'; 124 *$AUTOLOAD = eval $code; 125 } 126 127 goto &$AUTOLOAD; 128} 129 1301; 131