WWW-Freshmeat-0.22000755000000000000 011723053506 14366 5ustar00unknownunknown000000000000WWW-Freshmeat-0.22/Build.PL000444000000000000 202011454534253 16015 0ustar00unknownunknown000000000000use 5.008; use strict; use warnings; use Module::Build; my $builder = Module::Build->new( module_name => 'WWW::Freshmeat', license => 'perl', dist_author => 'Alexandr Ciornii ', dist_version_from => 'lib/WWW/Freshmeat.pm', requires => { 'LWP::UserAgent' => 0, 'XML::Simple' => 0, 'XML::Parser' => 0, #for XML::Simple, in case of dependency problems 'perl' => 5.008, #'HTML::TreeBuilder::XPath' => 0.09, 'Mouse' => 0.24, #recent one }, build_requires => { 'Test::More' => 0.17, #isa_ok 'LWP::Online' => 1.06, 'File::Slurp' => 0, }, meta_merge => { resources=> { repository => 'http://github.com/chorny/WWW-Freshmeat', Ohloh => 'https://www.ohloh.net/p/WWW-Freshmeat', }, keywords => ['freshmeat','API'], }, add_to_cleanup => [ 'WWW-Freshmeat-*' ], ); $builder->create_build_script(); WWW-Freshmeat-0.22/Changes000444000000000000 477311723053131 16023 0ustar00unknownunknown000000000000Revision history for WWW-Freshmeat 0.22 2012-02-28 - 'Mirror site' will map to 'url_mirror' - Compatibility support for old urls that now redirect to freecode.com 0.21 2009-12-29 - redir_url will return string, not an URI object 0.20 2009-11-08 - Updates for new API - 'retrieve_user' temporarily removed - "url_list", "branches", "trove_id", "real_author", "maintainers", "url", "init_html", "popularity" were removed - 'release_date' temporarily removed - 'languages','tags' methods added - example removed 0.13 not released - method version will return empty string when there is no release - new project methods: release_date, maintainers, date_add, date_updated - WWW::Freshmeat::User added - example added 0.12 2009-02-18 - added $WWW::Freshmeat::Project::project_re - regexp for project name - url_list will work with projects containing '.' - added real_author to fetch name of author (not maintainer) 0.11 2009-02-15 - url_list has argument to try to follow Freshmeat redirect links - rewrote redir_url not to fetch page it was redirected to 0.10 2009-02-14 - 5.008 only (due to 'ISO-8859-1' encoding of XML file) - projectname_short project method for retrieving project string id - HTML::TreeBuilder::XPath is now required - supports fetching branch list - url_list project method for retrieving project URL list - popularity project method for retrieving project popularity data - redir_url in WWW::Freshmeat to fetch url which link will redirect to 0.03 2009-02-03 - retrieve_project for project that does not exist will return undef - retrieve_project will die if it would not be able to fetch project record - nonexistingproject.t to test this functionality - method for returning id's of trove categories - project_from_xml class method - tests check for connection with LWP::Online - Build.PL now lists modules in 'requires' section 0.02 2009-01-25 new maintainer: Alexandr Ciornii - distribution modernized - "project.t" added, a live test - "boilerplate.t" removed - "all rights reserved" removed (by permission of Cedric Bouvier) 0.01 Wed May 31 13:29:17 CEST 2006 First version, only retrieval of known project entry. WWW-Freshmeat-0.22/Makefile.PL000444000000000000 175311454534264 16511 0ustar00unknownunknown000000000000use 5.008; use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'WWW::Freshmeat', AUTHOR => 'Alexandr Ciornii ', VERSION_FROM => 'lib/WWW/Freshmeat.pm', ABSTRACT_FROM => 'lib/WWW/Freshmeat.pm', PL_FILES => {}, PREREQ_PM => { 'Test::More' => 0.17, #isa_ok 'LWP::UserAgent' => 0, 'XML::Simple' => 0, 'XML::Parser' => 0, #for XML::Simple, in case of dependency problems 'LWP::Online' => 1.06, #'HTML::TreeBuilder::XPath' => 0.09, 'Mouse' => 0.24, #recent one 'File::Slurp' => 0, }, ($ExtUtils::MakeMaker::VERSION ge '6.31'? ('LICENSE' => 'perl', ) : ()), ($ExtUtils::MakeMaker::VERSION ge '6.48'? ('MIN_PERL_VERSION' => 5.008,) : ()), dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'WWW-Freshmeat-*' }, ); WWW-Freshmeat-0.22/MANIFEST000444000000000000 50611723053506 15635 0ustar00unknownunknown000000000000Build.PL Makefile.PL Changes lib/WWW/Freshmeat.pm lib/WWW/Freshmeat/Project.pm lib/WWW/Freshmeat/Project/URL.pm lib/WWW/Freshmeat/User.pm MANIFEST META.yml # Will be created by "make dist" README t/00-load.t t/pod-coverage.t t/pod.t t/project.t t/project-mojo.t t/mojomojo.xml t/hook_lexwrap.xml META.json WWW-Freshmeat-0.22/META.json000444000000000000 347411723053506 16154 0ustar00unknownunknown000000000000{ "abstract" : "automates usage of Freshmeat.net", "author" : [ "Alexandr Ciornii " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.38, CPAN::Meta::Converter version 2.112150", "keywords" : [ "freshmeat", "API" ], "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "WWW-Freshmeat", "prereqs" : { "build" : { "requires" : { "File::Slurp" : 0, "LWP::Online" : "1.06", "Test::More" : "0.17" } }, "configure" : { "requires" : { "Module::Build" : "0.38" } }, "runtime" : { "requires" : { "LWP::UserAgent" : 0, "Mouse" : "0.24", "XML::Parser" : 0, "XML::Simple" : 0, "perl" : "5.008" } } }, "provides" : { "WWW::Freshmeat" : { "file" : "lib/WWW/Freshmeat.pm", "version" : "0.22" }, "WWW::Freshmeat::Project" : { "file" : "lib/WWW/Freshmeat/Project.pm", "version" : "0.22" }, "WWW::Freshmeat::Project::URL" : { "file" : "lib/WWW/Freshmeat/Project/URL.pm", "version" : "0.22" }, "WWW::Freshmeat::User" : { "file" : "lib/WWW/Freshmeat/User.pm", "version" : "0.22" } }, "release_status" : "stable", "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "http://github.com/chorny/WWW-Freshmeat" }, "x_Ohloh" : "https://www.ohloh.net/p/WWW-Freshmeat" }, "version" : "0.22" } WWW-Freshmeat-0.22/META.yml000444000000000000 212311723053506 15772 0ustar00unknownunknown000000000000--- abstract: automates usage of Freshmeat.net author: - 'Alexandr Ciornii ' build_requires: File::Slurp: 0 LWP::Online: 1.06 Test::More: 0.17 configure_requires: Module::Build: 0.38 dynamic_config: 1 generated_by: 'Module::Build version 0.38, CPAN::Meta::Converter version 2.112150' keywords: - freshmeat - API license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: WWW-Freshmeat provides: WWW::Freshmeat: file: lib/WWW/Freshmeat.pm version: 0.22 WWW::Freshmeat::Project: file: lib/WWW/Freshmeat/Project.pm version: 0.22 WWW::Freshmeat::Project::URL: file: lib/WWW/Freshmeat/Project/URL.pm version: 0.22 WWW::Freshmeat::User: file: lib/WWW/Freshmeat/User.pm version: 0.22 requires: LWP::UserAgent: 0 Mouse: 0.24 XML::Parser: 0 XML::Simple: 0 perl: 5.008 resources: license: http://dev.perl.org/licenses/ repository: http://github.com/chorny/WWW-Freshmeat x_Ohloh: https://www.ohloh.net/p/WWW-Freshmeat version: 0.22 WWW-Freshmeat-0.22/README000444000000000000 242011257453367 15414 0ustar00unknownunknown000000000000WWW-Freshmeat This modules aims at automating searches for Free Software project entries in the Freshmeat.net directory. It is currently in very alpha stage, with very limited functionality (retrieving data for a project you already know of). INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install Alternatively, to install with Module::Build, you can use the following commands: perl Build.PL ./Build ./Build test ./Build install SUPPORT AND DOCUMENTATION After installing, you can find documentation for this module with the perldoc command. perldoc WWW::Freshmeat You can also look for information at: Search CPAN http://search.cpan.org/dist/WWW-Freshmeat CPAN Request Tracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=WWW-Freshmeat AnnoCPAN, annotated CPAN documentation: http://annocpan.org/dist/WWW-Freshmeat CPAN Ratings: http://cpanratings.perl.org/d/WWW-Freshmeat COPYRIGHT AND LICENCE Copyright 2006 Cedric Bouvier (version 0.01). Copyright (C) 2009 Alexandr Ciornii. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. WWW-Freshmeat-0.22/lib000755000000000000 011723053506 15134 5ustar00unknownunknown000000000000WWW-Freshmeat-0.22/lib/WWW000755000000000000 011723053506 15620 5ustar00unknownunknown000000000000WWW-Freshmeat-0.22/lib/WWW/Freshmeat.pm000444000000000000 1131611723053435 20254 0ustar00unknownunknown000000000000package WWW::Freshmeat; use 5.008; use strict; use warnings; =head1 NAME WWW::Freshmeat - automates usage of Freshmeat.net =head1 VERSION Version 0.22 =cut our $VERSION = '0.22'; use XML::Simple qw(); use WWW::Freshmeat::Project; use Carp; =head1 SYNOPSIS use WWW::Freshmeat; my $fm = WWW::Freshmeat->new(token=>'freshmeat_token'); my $project = $fm->retrieve_project('project_id'); foreach my $p ( @projects, $project ) { print $p->name(), "\n"; print $p->version(), "\n"; print $p->description(), "\n"; } =cut package WWW::Freshmeat; use base qw( LWP::UserAgent ); sub new { my $class=shift; my $self=LWP::UserAgent->new(); bless $self,$class; my %data=@_; $self->{fm_token}=$data{token}; return $self; } sub _token { my $self = shift; croak "No token" unless $self->{fm_token}; return $self->{fm_token}; } =head1 DESCRIPTION C derives from C, so it accepts all the methods that C does, notably C, C, C... =head2 Methods =over 4 =item B I Query the freshmeat.net site for the project I (should be the Freshmeat ID of the requested project) and returns a C object or undef if the project entry cannot be found. =cut sub retrieve_project { my $self = shift; my $id = shift; my $url = "http://freshmeat.net/projects/$id.xml?auth_code=".$self->_token; my $response = $self->get($url); if ($response->is_success) { my $xml = $response->content(); return $self->project_from_xml($xml); } else { if ($response->code eq '404') { return undef; } else { die "Could not GET freshmeat project (".$response->status_line.")"; } } } =item B I Receives Freshmeat project XML record and returns a C object or undef if the project entry cannot be found. =cut sub project_from_xml { my $self = shift; my $xml = shift; if ($xml eq 'Error: project not found.') { return undef; } die "XML is empty" unless $xml; my $data = XML::Simple::XMLin($xml,ForceArray => ['approved-url','recent-release']); #die unless exists $data->{'project'}; die unless $data->{'name'}; return WWW::Freshmeat::Project->new($data, $self); #->{'project'} } sub retrieve_user { croak "'User' is temporarily removed"; my $self = shift; my $id = shift; require WWW::Freshmeat::User; return WWW::Freshmeat::User->new($self,$id); } =item B I Receives URL and returns URL which it redirects to. =cut sub redir_url { my $self = shift; my $url=shift; $self->requests_redirectable([]); my $response = $self->get($url) or return $url; if ($response->is_redirect) { #http://www.perlmonks.org/?node_id=147608 my $referral_uri = $response->header('Location'); { # Some servers erroneously return a relative URL for redirects, # so make it absolute if it not already is. local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1; my $base = $response->base; $referral_uri = $HTTP::URI_CLASS->new($referral_uri, $base) ->abs($base)->as_string; } return $referral_uri; } else { return $url; } } =back =head1 SEE ALSO L. =head1 AUTHOR Cedric Bouvier, C<< >>. Alexandr Ciornii. =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc WWW::Freshmeat You can also look for information at: =over 4 =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * RT: CPAN's request tracker L =item * Search CPAN L =back =head1 ACKNOWLEDGEMENTS =head1 COPYRIGHT & LICENSE Copyright 2006 Cedric Bouvier (version 0.01). Copyright 2009-2012 Alexandr Ciornii. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; # End of WWW::Freshmeat WWW-Freshmeat-0.22/lib/WWW/Freshmeat000755000000000000 011723053506 17536 5ustar00unknownunknown000000000000WWW-Freshmeat-0.22/lib/WWW/Freshmeat/Project.pm000444000000000000 2452511723053160 21663 0ustar00unknownunknown000000000000package WWW::Freshmeat::Project; use 5.008; use strict; use warnings; use WWW::Freshmeat::Project::URL; use Carp; our $VERSION = '0.22'; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self=bless shift, $class; $self->{www_freshmeat} = shift || die; return $self; } my %new_api_map=('www_freshmeat'=>'www_freshmeat','desc_short'=>'oneliner', 'desc_full'=>'description','projectname_full'=>'name','projectname_short'=>'permalink'); foreach my $field ( qw(url_homepage projectname_full desc_short desc_full license www_freshmeat projectname_short) ) { no strict 'refs'; my $xml_field=$new_api_map{$field}; if ($xml_field) { *$field = sub { my $self = shift; my $value = $self->{$xml_field}; if ( ref($value) && ref($value) eq 'HASH' && !(keys %$value) ) { return undef; } else { return $value; } } } else { *$field = sub { croak "'$field' method was removed"; } } } sub name { $_[0]->{name} } sub description { $_[0]->desc_full(@_) || $_[0]->desc_short(@_) } sub url_project_page { my $self = shift; return 'http://freshmeat.net/projects/'.$self->{'permalink'}; } sub languages { my $self = shift; my $lang = $self->{'programming-language-list'}; return (split /,\s*/,$lang); } sub tags { my $self = shift; my $tags = $self->{'tag-list'}; return (split /,\s*/,$tags); } sub trove_id { croak "method was removed"; #$_[0]{descriminators}{trove_id} } sub version { my $self=shift; return '' unless exists $self->{'recent-releases'}{'recent-release'}; my @versions=@{$self->{'recent-releases'}{'recent-release'}}; return $versions[0]->{'version'}; } sub release_date { croak "'release_date' is temporarily removed"; my $dt=$_[0]{latest_release}{latest_release_date}; if (ref($dt) eq 'HASH') { return ''; } else { if ($dt eq '1970-01-01 00:00:00') { return ''; } else { return $dt; } } } sub date_add { my $dt=$_[0]{'created-at'}{'content'}; if (ref($dt)) { # eq 'HASH' die ref($dt); return ''; } else { if ($dt eq '1970-01-01 00:00:00' or $dt eq '1970-01-01T00:00:00Z') { die; } else { $dt=~s/T/ /g;$dt=~s/Z$//g; #get rid ot T and Z in '2009-01-22T14:58:27Z' die if $dt=~/[a-zA-Z]/; return $dt; } } } sub date_updated { my $dt=$_[0]{'updated-at'}{'content'}; if (ref($dt)) { # eq 'HASH' die ref($dt); return ''; } else { if ($dt eq '1970-01-01 00:00:00' or $dt eq '1970-01-01T00:00:00Z') { die; } else { $dt=~s/T/ /g;$dt=~s/Z$//g; #get rid ot T and Z in '2009-01-22T14:58:27Z' die if $dt=~/[a-zA-Z]/; return $dt; } } } sub maintainers { croak "removed"; my $authors=$_[0]{authors}{author}; if (ref($authors) eq 'HASH') { if (keys %$authors>0) { return ($authors->{author_name}); #$authors=[$authors]; } else { return (); } } elsif (ref($authors) eq 'SCALAR') { die; #$authors=[$authors]; } return map { $_->{author_name} } @$authors; } sub url { croak "removed"; my $self = shift; return $self->{url} if $self->{url}; my $freshmeat_url = $self->{url_project_page}; my $url = $self->url_homepage() or return; $self->{url} = $self->www_freshmeat()->redir_url($url); return $self->{url}; } sub init_html { croak "removed"; my $self = shift; my $html = shift; #require HTML::TreeBuilder::XPath; $self->{_html}=HTML::TreeBuilder::XPath->new_from_content($html); } sub _html_tree { croak "removed"; my $self = shift; if (!$self->{_html}) { my $id=$self->projectname_short(); my $url = "http://freshmeat.net/projects/$id/"; $self->www_freshmeat()->agent('User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.19) Gecko/20081201 Firefox/2.0.0.19'); my $response = $self->www_freshmeat()->get($url); my $html = $response->content(); if ($response->is_success) { $self->init_html($html); } else { die "Could not GET $url (".$response->status_line.", $html)"; } } return $self->{_html}; } sub branches { croak "removed"; =for cmt my $self = shift; my $tree=$self->_html_tree(); my $nodes=$tree->findnodes(q{//table/tr/th/b[text()='Branch']/../../following-sibling::tr/td[1]/a}); my %list; while (my $node=$nodes->shift) { if ($node->attr('href') =~m#/branches/(\d+)/#) { $list{$1}=$node->as_text(); } else { die; } } return %list; =cut } our $project_re=qr/[a-z0-9_\-\.!]+/; sub url_list { croak "removed"; =for cmt my $self = shift; my $real=(@_>0?1:0); my $tree=$self->_html_tree(); my $nodes=$tree->findnodes(q{/html/body/div/table/tr/td/table/tr/td/p/a[@href=~/\/redir/]}); #/ my %list; while (my $node=$nodes->shift) { if ($node->attr('href') =~m#/redir/$project_re/\d+/(url_\w+)/#) { my $type=$1; my $text=$node->as_text(); if ($text=~/\Q[..]\E/) { if ($real) { $list{$type}=$self->www_freshmeat()->redir_url('http://freshmeat.net'.$node->attr('href')); } else { $list{$type}=$node->attr('href'); } } else { $list{$type}=$text; } } else { die "bad link:".$node->attr('href'); } } return %list; =cut } sub url_list1 { my $self = shift; die unless $self->isa('WWW::Freshmeat::Project'); my $url_xml=$self->{'approved-urls'}{'approved-url'}; die unless $url_xml; my @urls; my %dedupe; foreach my $a_url (@$url_xml) { die unless $a_url->{type} eq 'Url'; my $concatenated=$a_url->{permalink}.$a_url->{label}; next if $dedupe{$concatenated}; $dedupe{$concatenated}=1; #my $a_url1=$a_url->{'content'}; my $url=WWW::Freshmeat::Project::URL->new( (map {$_=>$a_url->{$_}} qw/label redirector host/), www_freshmeat=>$self->{www_freshmeat}, ); push @urls,$url; #if (1) { #} else { # die "bad link:"; #} } return @urls; #return %list; } my %detect_url_types=('website'=>'url_homepage', 'homepage'=>'url_homepage', 'home'=>'url_homepage', lc 'Download'=>'url_download', 'bug tracker'=>'url_bugtracker', lc 'GitHub source repo' => 'url_cvs', lc 'Repository' => 'url_cvs', 'cpan' => 'url_mirror', lc 'Mirror site' => 'url_mirror', ); #url_changelog #url_download #url_cvs #url_mirror sub detect_link_types { my $self = shift; my $urls = shift; my %type_set; foreach my $url (@$urls) { my $type=$detect_url_types{lc $url->{label}} || ''; #$type_set{$type} ||= []; if (exists $type_set{$type}) { if (ref $type_set{$type} eq 'ARRAY') { push @{$type_set{$type}},$url; } else { $type_set{$type}=[$type_set{$type},$url]; } } else { $type_set{$type}=$url; } #if ($type) { #} else } return \%type_set; } my %popularity_conv=('Record hits'=>'record_hits','URL hits'=>'url_hits','Subscribers'=>'subscribers'); sub popularity { croak "removed"; my $self = shift; my $tree=$self->_html_tree(); my $nodes=$tree->findnodes(q{/html/body/div[1]/table/tr/td[2]/table/tr[3]/td[3]/table[2]/tr/td/small}); my %list; if (my $node=$nodes->shift) { my $text=$node->as_text(); $text=~s/à/ /g; my @list=grep {$_} split /|\s{4}/,$text; foreach my $s (@list) { $s=~s/^(?:^ |\s)+//s; $s=~s/\s+$//s; #print "F:$s\n"; if ($s=~/(\w[\w\s]+\w):\s+([\d,]+)/ and exists $popularity_conv{$1}) { my $type=$popularity_conv{$1}; my $num=$2; $num=~s/,//g; $list{$type}=$num; } else { die "Cannot find popularity record: '$s'"; } } } else { die "Cannot find popularity data"; } return %list; } sub real_author { croak "removed"; my $self = shift; my $tree=$self->_html_tree(); my $nodes=$tree->findnodes(q{/html/body/div[1]/table/tr/td[2]/table/tr[3]/td[1]/p[2]/b/..}); my %list; if (my $node=$nodes->shift) { my $text=$node->as_text; $text=~s/^Author:\s+//s; $text=~s/\s+\Q[contact developer]\E\s*$//s; $text=~s/\s+<[^<>]+>\s*$//s; return $text; } } =head2 WWW::Freshmeat::Project methods The C object provides some of the fields from the freshmeat.net entry through the following methods =over 4 =item B URL of project page on Freshmeat =item B deprecated =item B =item B =item B =item B =item B Removed. =item B =item B =back Additionally, it provides the following "higher-level" methods: =over 4 =item B =item B Return either C (respectively C) or C (respectively C) if the former is empty. =item B Returns the version of the latest release. =item B Removed. C returns a freshmeat.net URL that redirects to the actual project's home page. This url() method tries to follow the redirection and returns the actual homepage URL if it can be found, or the URL to the freshmeat.net entry for the project. =item B Removed. List of branches for project. Returns hash in form of (branch id => branch name). =item B Removed. Freshmeat popularity data for project. Returns hash with keys record_hits, url_hits, subscribers =item B Removed. =item B Returns list of URLs for project. Each URL is a WWW::Freshmeat::Project::URL object. =item B Removed. Returns name of author (not maintainer). =item B Removed. Returns date of latest release. =item B Removed. Returns list of names of maintainers. =back 1; WWW-Freshmeat-0.22/lib/WWW/Freshmeat/User.pm000444000000000000 323211723053163 21146 0ustar00unknownunknown000000000000package WWW::Freshmeat::User; use strict; use warnings; use WWW::Freshmeat (); use Carp; our $VERSION = '0.22'; sub init_html { croak "removed"; my $self = shift; my $html = shift; require HTML::TreeBuilder::XPath; $self->{_html}=HTML::TreeBuilder::XPath->new_from_content($html); } sub _html_tree { my $self = shift; if (!$self->{_html}) { my $id=$self->{id}; my $url = "http://freshmeat.net/~$id/"; $self->{www_freshmeat}->agent('User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.19) Gecko/20081201 Firefox/2.0.0.19'); my $response = $self->{www_freshmeat}->get($url); my $html = $response->content(); if ($response->is_success) { if ($html=~m#

\s*Invalid user ID\s*

#s) { return; } $self->init_html($html); } else { die "Could not GET $url (".$response->status_line.", $html)"; } } return $self->{_html}; } sub new { croak "removed"; my $proto = shift; my $class = ref($proto) || $proto; my $self = bless {}, $class; $self->{www_freshmeat} = shift; $self->{id} = shift; return $self; } sub projects { my $self = shift; my $tree=$self->_html_tree(); my $xpath=q{/html/body/div[1]/table/tr/td[2]/table/tr[1]/td[2]/p/ul[1]/li/a}; my $nodes=$tree->findnodes($xpath); my @list; while (my $node=$nodes->shift) { if ($node->attr('href') =~m#/projects/($WWW::Freshmeat::Project::project_re)/#) { push @list,$1; } else { die; } } return @list; } 1 # (c) Alexandr Ciornii, 2009 WWW-Freshmeat-0.22/lib/WWW/Freshmeat/Project000755000000000000 011723053506 21144 5ustar00unknownunknown000000000000WWW-Freshmeat-0.22/lib/WWW/Freshmeat/Project/URL.pm000444000000000000 127111723053170 22277 0ustar00unknownunknown000000000000package WWW::Freshmeat::Project::URL; use Mouse; use Carp; our $VERSION = '0.22'; has 'url' => (is => 'rw', isa => 'Str', 'builder'=>'_find_url','lazy'=>1); has 'label' => (is => 'rw', isa => 'Str',required=>1); has 'redirector' => (is => 'rw', isa => 'Str'); has 'host' => (is => 'rw', isa => 'Str'); has 'www_freshmeat' => (is => 'rw', isa => 'WWW::Freshmeat',required=>1); no Mouse; sub _find_url { my $self=shift || die; croak "No 'redirector' field" unless $self->redirector; my $u=$self->www_freshmeat->redir_url($self->redirector); if (substr($u,0,25) eq 'http://freecode.com/urls/') { $u=$self->www_freshmeat->redir_url($u); } return $u; } 1; WWW-Freshmeat-0.22/t000755000000000000 011723053506 14631 5ustar00unknownunknown000000000000WWW-Freshmeat-0.22/t/00-load.t000444000000000000 24111254273607 16271 0ustar00unknownunknown000000000000#!perl -T use Test::More tests => 1; BEGIN { use_ok( 'WWW::Freshmeat' ); } diag( "Testing WWW::Freshmeat $WWW::Freshmeat::VERSION, Perl $], $^X" ); WWW-Freshmeat-0.22/t/hook_lexwrap.xml000444000000000000 437311254477647 20240 0ustar00unknownunknown000000000000 2008-12-29T17:18:24Z Hook::LexWrap allows you to install a pre- or post-wrapper (or both) around an existing subroutine. Unlike other modules that provide this capacity (e.g. Hook::PreAndPost and Hook::WrapSub), Hook::LexWrap implements wrappers in such a way that the standard 'caller' function works correctly within the wrapped subroutine. Hook::LexWrap Lexically scoped subroutine wrappers in Perl. hook_lexwrap 12.92 2008-12-29T18:48:04Z 1.0 Software Development, Libraries, Perl Modules Perl OS Independent Perl 1 53 0 2008-12-29T18:48:04Z 291107 0.22 Initial freshmeat announcement 63210 854d57e030b1b55bb959ab066144c62d http://freshmeat.net/urls/854d57e030b1b55bb959ab066144c62d rt.cpan.org 123211 958a46b0fd68b07418a150fc730dd5a1 http://freshmeat.net/urls/958a46b0fd68b07418a150fc730dd5a1 search.cpan.org WWW-Freshmeat-0.22/t/mojomojo.xml000444000000000000 1515511254277740 17377 0ustar00unknownunknown000000000000 2009-01-22T14:58:27Z MojoMojo is a Web2.0 wiki with AJAX live preview, hierarchical structure, tags, diffs, pluggable syntax, permissions/ACL, attachments, RSS feeds, a photo gallery, edit conflict resolution via 3-way merge, themes/skinning, localization, built-in full-text search, and a reverse index. Since it's built on top of the Perl Catalyst Web framework, MojoMojo supports any Web server, and includes its own standalone one. It also support any database backend supported by the DBIx::Class ORM, and has been successfully tested with PostgreSQL, SQLite, and MySQL. MojoMojo A Perl/Catalyst-based hierarchical Web 2.0 wiki with AJAX preview, tags, etc. mojomojo 191.25 2009-08-03T08:05:25Z 5.2 Wiki, CMS, Web 2.0 Ubuntu, Mac OS X, FreeBSD, Windows SQLite, jQuery, postgresql Polish, Japanese, Catalan, French, German, Norwegian, English, Russian, Spanish 2 60 10 2009-08-03T08:05:25Z Highlights of this release include numerous contributions, including a better design of the navigation and editing UI. First-time users will have an easier time thanks to friendlier database spawning and removal of non-user-serviceable options from the configuration file into MojoMojo.pm. Angle brackets are now preserved in code blocks. Perl comments render correctly in syntax highlighted code. Better markup code is inserted by the edit toolbar buttons. 303385 0.999032 redesign, autarch, formatter, syntax highlight, angle brackets 2009-07-29T14:12:50Z Session caching was improved. Remote img src URLs are allowed. POD documentation was written. Bugs were fixed. 303208 0.999031 Minor bugfixes, Minor Enhancements 2009-05-11T00:04:20Z Better XSS prevention and more testing of the code base. Reworking of the Formatter chain. More theme choices. More Formatter plugins: RSS Feeds, Amazon, and Emoticons. 299207 0.999029 Minor 2009-04-25T08:48:19Z This release includes a full cleanup of the template set, Polish, Russian, Catalan, and Spanish translations, a new theme (Catalyst homepage) and a CPAN module formatter as well as DocBook and file-include formatters. There were also JQuery improvements including maximize support, sticky JavaScript-based vertical/horizontal split edit, drop-downs for syntax highlighters, and reCAPTCHA support for anti-spam. 298392 0.999028 2009-02-20T18:43:00Z This release adds a Japanese translation. It adds "Split Edit" for side-by-side view/edit. It supports merge for overlapping edits. It has switched from Cache::Store::Memory to Cache::FastMmap. It changes search results by link to link to ROOT/$author instead of author at page level. It shows the bread crumb path on search results, linking the terminal node. It lists one link for each page by an author via .users (instead of all revisions). It fixes broken authors (users) pager links. 294581 0.999027 Minor feature enhancements 39578 105ac83fcb89c30e30347de95cde4e5a http://freshmeat.net/urls/105ac83fcb89c30e30347de95cde4e5a mojomojo.ideascale.com 63259 2a70a6ab4c743fa3ba2e1d582885142a http://freshmeat.net/urls/2a70a6ab4c743fa3ba2e1d582885142a twitter.com 83403 d9041eaa4cb28430a73fb705457069f4 http://freshmeat.net/urls/d9041eaa4cb28430a73fb705457069f4 github.com 123415 d9041eaa4cb28430a73fb705457069f4 http://freshmeat.net/urls/d9041eaa4cb28430a73fb705457069f4 github.com 131288 d0c6767b898a897ee25d47b82826c6a2 http://freshmeat.net/urls/d0c6767b898a897ee25d47b82826c6a2 mojomojo.org 2009-03-14T20:01:30Z 22667 http://freshmeat.net/screenshots/8e/16/8e1625e76ea3c53892d05db914825583_thumb.png?1237060889 WWW-Freshmeat-0.22/t/pod-coverage.t000444000000000000 31111257405364 17506 0ustar00unknownunknown000000000000#!perl -T use Test::More; plan skip_all; exit; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; all_pod_coverage_ok(); WWW-Freshmeat-0.22/t/pod.t000444000000000000 22211254273607 15716 0ustar00unknownunknown000000000000#!perl -T use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok(); WWW-Freshmeat-0.22/t/project-mojo.t000444000000000000 71111256157006 17543 0ustar00unknownunknown000000000000#!perl use 5.006; use strict; use warnings; use Test::More tests => 5; use File::Slurp; use WWW::Freshmeat 0.12; my $fm = WWW::Freshmeat->new(); isa_ok($fm,'WWW::Freshmeat'); my $xml=read_file('t/mojomojo.xml'); my $project = $fm->project_from_xml($xml); isa_ok($project,'WWW::Freshmeat::Project'); is($project->name(),'MojoMojo'); is($project->date_add(),'2009-01-22 14:58:27'); is($project->date_updated(),'2009-08-03 08:05:25'); WWW-Freshmeat-0.22/t/project.t000444000000000000 456611275623771 16645 0ustar00unknownunknown000000000000#!perl use strict; use warnings; use LWP::Online ':skip_all'; use Test::More tests => 16; use File::Slurp; use WWW::Freshmeat 0.20; my $fm = WWW::Freshmeat->new(); isa_ok($fm,'WWW::Freshmeat'); my $xml=read_file((-e 't'?'t/':'').'hook_lexwrap.xml'); my $project = $fm->project_from_xml($xml); #my $project = $fm->retrieve_project('hook_lexwrap'); isa_ok($project,'WWW::Freshmeat::Project'); isa_ok($project->www_freshmeat,'WWW::Freshmeat'); is($project->name(),'Hook::LexWrap'); is($project->version(),'0.22'); #is($project->url(),'http://search.cpan.org/dist/Hook-LexWrap/'); #is($project->license(),'Perl License'); =for cmt my @trove=@{$project->trove_id()}; my %hash; @hash{@trove}=(); foreach my $t (11,3,902,235,176,809,910) { ok(exists $hash{$t},"id $t is present"); } #902 - OSI Approved :: Perl License #176 - Perl #910 - Software Development :: Libraries :: Perl Modules =cut is($project->projectname_short(),'hook_lexwrap'); my @list=$project->url_list1; is(scalar(@list),2); is_deeply($list[0], { label=>'Bug Tracker', redirector=>'http://freshmeat.net/urls/854d57e030b1b55bb959ab066144c62d', host=>'rt.cpan.org', www_freshmeat=>$project->www_freshmeat, },'correct link to Bug Tracker'); is_deeply($list[1], { label=>'Website', redirector=>'http://freshmeat.net/urls/958a46b0fd68b07418a150fc730dd5a1', host=>'search.cpan.org', www_freshmeat=>$project->www_freshmeat, },'correct link to Website'); my $hash=$project->detect_link_types(\@list); ok(exists $hash->{'url_homepage'}); is($hash->{'url_homepage'}->host,'search.cpan.org'); is($hash->{'url_homepage'}->url,'http://search.cpan.org/dist/Hook-LexWrap/'); ok(exists $hash->{'url_bugtracker'}); is($hash->{'url_bugtracker'}->url,'http://rt.cpan.org/NoAuth/Bugs.html?Dist=Hook-LexWrap'); { my @lang=$project->languages; is($lang[0],'Perl'); } is_deeply([$project->tags],['Software Development', 'Libraries', 'Perl Modules']); =for cmt is_deeply({$project->branches()},{'77120'=>'Default'},'branches'); my %pop=$project->popularity(); cmp_ok($pop{'record_hits'},'>=',442); cmp_ok($pop{'url_hits'},'>=',216); cmp_ok($pop{'subscribers'},'>=',0); is($project->real_author(),'Damian Conway'); is_deeply([$project->maintainers],['Alexandr Ciornii']); cmp_ok($project->release_date,'ge','2008-12-29 18:48:04'); =cut