├── .gitignore ├── t └── 00_compile.t ├── .shipit ├── xt ├── synopsis.t ├── pod.t ├── perlcritic.t └── podspell.t ├── MANIFEST.SKIP ├── Changes ├── Makefile.PL ├── README ├── eg └── stream-client.pl ├── MANIFEST └── lib └── AnyEvent └── Atom ├── Stream └── UserAgent.pm └── Stream.pm /.gitignore: -------------------------------------------------------------------------------- 1 | META.yml 2 | Makefile 3 | inc/ 4 | pm_to_blib 5 | *~ 6 | -------------------------------------------------------------------------------- /t/00_compile.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use Test::More tests => 1; 3 | 4 | BEGIN { use_ok 'AnyEvent::Atom::Stream' } 5 | -------------------------------------------------------------------------------- /.shipit: -------------------------------------------------------------------------------- 1 | steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist, UploadCPAN 2 | git.push_to = origin 3 | -------------------------------------------------------------------------------- /xt/synopsis.t: -------------------------------------------------------------------------------- 1 | use Test::More; 2 | eval "use Test::Synopsis"; 3 | plan skip_all => "Test::Synopsis required" if $@; 4 | all_synopsis_ok(); 5 | -------------------------------------------------------------------------------- /xt/pod.t: -------------------------------------------------------------------------------- 1 | use Test::More; 2 | eval "use Test::Pod 1.00"; 3 | plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; 4 | all_pod_files_ok(); 5 | -------------------------------------------------------------------------------- /xt/perlcritic.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use Test::More; 3 | eval q{ use Test::Perl::Critic }; 4 | plan skip_all => "Test::Perl::Critic is not installed." if $@; 5 | all_critic_ok("lib"); 6 | -------------------------------------------------------------------------------- /MANIFEST.SKIP: -------------------------------------------------------------------------------- 1 | \bRCS\b 2 | \bCVS\b 3 | \.svn/ 4 | \.git/ 5 | ^MANIFEST\. 6 | ^Makefile$ 7 | ~$ 8 | \.old$ 9 | ^blib/ 10 | ^pm_to_blib 11 | ^MakeMaker-\d 12 | \.gz$ 13 | \.cvsignore 14 | \.shipit 15 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for Perl extension AnyEvent::Atom::Stream 2 | 3 | 0.02 Thu Jul 16 21:21:18 PDT 2009 4 | - Simplify AnyEvent::HTTP usage using on_body (Thanks to typester) 5 | 6 | 0.01 Thu Jul 16 18:51:17 2009 7 | - original version 8 | -------------------------------------------------------------------------------- /xt/podspell.t: -------------------------------------------------------------------------------- 1 | use Test::More; 2 | eval q{ use Test::Spelling }; 3 | plan skip_all => "Test::Spelling is not installed." if $@; 4 | add_stopwords(); 5 | set_spell_cmd("aspell -l en list"); 6 | all_pod_files_spelling_ok('lib'); 7 | __DATA__ 8 | Tatsuhiko 9 | Miyagawa 10 | -------------------------------------------------------------------------------- /Makefile.PL: -------------------------------------------------------------------------------- 1 | use inc::Module::Install; 2 | name 'AnyEvent-Atom-Stream'; 3 | all_from 'lib/AnyEvent/Atom/Stream.pm'; 4 | 5 | requires 'XML::Atom::Stream'; 6 | requires 'AnyEvent'; 7 | 8 | build_requires 'Test::More'; 9 | use_test_base; 10 | auto_include_deps; 11 | author_tests('xt'); 12 | auto_set_repository; 13 | WriteAll; 14 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is Perl module AnyEvent::Atom::Stream. 2 | 3 | INSTALLATION 4 | 5 | AnyEvent::Atom::Stream installation is straightforward. If your CPAN shell is set up, 6 | you should just be able to do 7 | 8 | % cpan AnyEvent::Atom::Stream 9 | 10 | Download it, unpack it, then build it as per the usual: 11 | 12 | % perl Makefile.PL 13 | % make && make test 14 | 15 | Then install it: 16 | 17 | % make install 18 | 19 | DOCUMENTATION 20 | 21 | AnyEvent::Atom::Stream documentation is available as in POD. So you can do: 22 | 23 | % perldoc AnyEvent::Atom::Stream 24 | 25 | to read the documentation online with your favorite pager. 26 | 27 | Tatsuhiko Miyagawa 28 | -------------------------------------------------------------------------------- /eg/stream-client.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use AnyEvent::Atom::Stream; 4 | 5 | my $url = "http://updates.sixapart.com/atom-stream.xml"; 6 | my $cv = AnyEvent->condvar; 7 | 8 | # API is compatible to XML::Atom::Stream 9 | binmode STDOUT, ":utf8"; 10 | 11 | my $client = AnyEvent::Atom::Stream->new( 12 | callback => sub { 13 | my $feed = shift; 14 | for my $entry ($feed->entries) { 15 | print $entry->title . 16 | ($feed->author ? " (by " . $feed->author->name . ")" : '') . "\n", 17 | " ", $entry->link->href, "\n"; 18 | print " (body: ", length($entry->content->body), " bytes)\n"; 19 | } 20 | }, 21 | timeout => 30, 22 | on_disconnect => $cv, 23 | ); 24 | 25 | my $guard = $client->connect($url); 26 | 27 | $cv->recv; 28 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | .gitignore 2 | Changes 3 | eg/stream-client.pl 4 | inc/Module/Install.pm 5 | inc/Module/Install/AuthorTests.pm 6 | inc/Module/Install/Base.pm 7 | inc/Module/Install/Can.pm 8 | inc/Module/Install/Fetch.pm 9 | inc/Module/Install/Include.pm 10 | inc/Module/Install/Makefile.pm 11 | inc/Module/Install/Metadata.pm 12 | inc/Module/Install/Repository.pm 13 | inc/Module/Install/TestBase.pm 14 | inc/Module/Install/Win32.pm 15 | inc/Module/Install/WriteAll.pm 16 | inc/Spiffy.pm 17 | inc/Test/Base.pm 18 | inc/Test/Base/Filter.pm 19 | inc/Test/Builder.pm 20 | inc/Test/Builder/Module.pm 21 | inc/Test/More.pm 22 | lib/AnyEvent/Atom/Stream.pm 23 | lib/AnyEvent/Atom/Stream/UserAgent.pm 24 | Makefile.PL 25 | MANIFEST This list of files 26 | META.yml 27 | README 28 | t/00_compile.t 29 | xt/perlcritic.t 30 | xt/pod.t 31 | xt/podspell.t 32 | xt/synopsis.t 33 | -------------------------------------------------------------------------------- /lib/AnyEvent/Atom/Stream/UserAgent.pm: -------------------------------------------------------------------------------- 1 | package AnyEvent::Atom::Stream::UserAgent; 2 | use strict; 3 | use AnyEvent; 4 | use AnyEvent::HTTP; 5 | 6 | sub new { 7 | my($class, $timeout, $on_disconnect) = @_; 8 | bless { 9 | timeout => $timeout, 10 | on_disconnect => $on_disconnect, 11 | }, shift; 12 | } 13 | 14 | sub get { 15 | my($self, $url, %args) = @_; 16 | 17 | my $content_cb = delete $args{":content_cb"}; 18 | my $disconn_cb = $args{on_disconnect} || sub { }; 19 | 20 | my %opts; 21 | $opts{timeout} = $self->{timeout} if $self->{timeout}; 22 | 23 | http_get $url, %opts, on_body => sub { 24 | my($body, $headers) = @_; 25 | local $XML::Atom::ForceUnicode = 1; 26 | $content_cb->($body); 27 | return 1; 28 | }, sub { 29 | my($body, $headers) = @_; 30 | $disconn_cb->($body); 31 | }; 32 | 33 | $self->{guard} = AnyEvent::Util::guard { 34 | undef $content_cb; # refs AnyEvent::Atom::Stream 35 | }; 36 | } 37 | 38 | 1; 39 | 40 | -------------------------------------------------------------------------------- /lib/AnyEvent/Atom/Stream.pm: -------------------------------------------------------------------------------- 1 | package AnyEvent::Atom::Stream; 2 | 3 | use strict; 4 | use 5.008_001; 5 | our $VERSION = '0.02'; 6 | 7 | use base qw( XML::Atom::Stream ); 8 | use AnyEvent::Atom::Stream::UserAgent; 9 | 10 | sub connect { 11 | my($self, $url) = @_; 12 | $self->{ua} = AnyEvent::Atom::Stream::UserAgent->new($self->{timeout}, $self->{on_disconnect}); 13 | $self->SUPER::connect($url); 14 | 15 | defined wantarray && AnyEvent::Util::guard { delete $self->{ua} }; 16 | } 17 | 18 | 1; 19 | __END__ 20 | 21 | =encoding utf-8 22 | 23 | =for stopwords 24 | 25 | =head1 NAME 26 | 27 | AnyEvent::Atom::Stream - XML::Atom::Stream with AnyEvent 28 | 29 | =head1 SYNOPSIS 30 | 31 | use AnyEvent::Atom::Stream; 32 | 33 | my $url = "http://updates.sixapart.com/atom-stream.xml"; 34 | my $cv = AnyEvent->condvar; 35 | 36 | # API is compatible to XML::Atom::Stream 37 | my $client = AnyEvent::Atom::Stream->new( 38 | callback => \&callback, 39 | timeout => 30, 40 | on_disconnect => $cv, 41 | ); 42 | my $guard = $client->connect($url); 43 | 44 | $cv->recv; 45 | 46 | sub callback { 47 | my($atom) = @_; 48 | # $atom is a XML::Atom::Feed object 49 | } 50 | 51 | =head1 DESCRIPTION 52 | 53 | AnyEvent::Atom::Stream is an XML::Atom::Stream subclass that uses 54 | AnyEvent::HTTP and thus allows you to run the stream listener using 55 | any of AnyEvent event loop implementation. 56 | 57 | =head1 METHODS 58 | 59 | =over 4 60 | 61 | =item new 62 | 63 | $client = AnyEvent::Atom::Stream->new( 64 | callback => \&callback, 65 | timeout => 30, 66 | on_disconnect => $cv, 67 | ); 68 | 69 | Creates a new AnyEvent::Atom::Stream instance. The API is compatible 70 | to XML::Atom::Stream, but it doesn't support C parameter, 71 | because that's something you can easily control with the new 72 | I AnyEvent callback. 73 | 74 | =item connect 75 | 76 | $guard = $client->connect($url); 77 | 78 | Connects and receives Atom update stream. 79 | 80 | =back 81 | 82 | =head1 AUTHOR 83 | 84 | Tatsuhiko Miyagawa Emiyagawa@bulknews.netE 85 | 86 | =head1 LICENSE 87 | 88 | This library is free software; you can redistribute it and/or modify 89 | it under the same terms as Perl itself. 90 | 91 | =head1 SEE ALSO 92 | 93 | L, L, L 94 | 95 | =cut 96 | --------------------------------------------------------------------------------