]>
iEval git - webservice-vichan.git/blob - lib/WebService/Vichan.pm
1 package WebService
::Vichan
;
6 use parent qw
/Exporter/;
11 use Time
::HiRes qw
/time sleep/;
13 our $VERSION = '0.001001';
16 our $last_request = 0;
17 our $ht = HTTP
::Tiny
->new(
18 agent
=> 'WebService-Vichan/'.$VERSION,
23 API_4CHAN
=> 'https://a.4cdn.org',
24 API_8CHAN
=> 'https://8ch.net',
27 our @EXPORT_OK = qw
/API_4CHAN API_8CHAN/;
28 our %EXPORT_TAGS = ( all
=> \
@EXPORT_OK );
31 my ($class, $url) = @_;
32 bless { url
=> $url }, $class
36 my ($url, $cached_result, $cached_timestamp) = @_;
38 if ($cached_timestamp) {
39 $options{headers
}{'If-Modified-Since'} = $cached_timestamp
41 my $time_since_last_request = time - $last_request;
42 sleep 1 - $time_since_last_request if $time_since_last_request < 1;
43 my $result = $ht->get($url, \
%options);
45 if ($result->{status
} == 304) {
46 [$cached_result, $cached_timestamp]
47 } elsif (!$result->{success
}) {
48 my $diestr = sprintf "Error requesting %s: %s\n", $url, $result->{reason
};
49 die $diestr unless $result->{success
};
51 [$result->{content
}, $last_request]
56 my ($self, $format, @args) = @_;
57 my $what = sprintf $format, @args;
58 my $url = $self->{url
} . '/' . $what;
59 my $result = $cache{$url};
60 if (!defined $result) {
61 $cache{$url} = do_request
$url
62 } elsif (time - $result->[1] > 10) {
63 $cache{$url} = do_request
$url, @
$result
65 decode_json
$cache{$url}->[0]
70 my $result = $self->requestf('boards.json');
71 $result = $result->{boards
} if ref $result eq 'HASH';
73 $_->{board
} //= $_->{uri
};
74 Hash
::Inflator
->new($_)
76 wantarray ?
@results : \
@results;
80 my ($self, $board) = @_;
81 $board = $board->{board
} if ref $board;
82 my $result = $self->requestf('%s/threads.json', $board);
83 my @pages = map { Hash
::Inflator
->new($_) } @
$result;
84 wantarray ?
@pages : \
@pages
88 my @pages = shift->threads(@_);
89 my @flat = map { @
{$_->{threads
}} } @pages;
90 wantarray ?
@flat : \
@flat
94 my ($self, $board) = @_;
95 $board = $board->{board
} if ref $board;
96 my $result = $self->requestf('%s/catalog.json', $board);
97 my @pages = map { Hash
::Inflator
->new($_) } @
$result;
98 wantarray ?
@pages : \
@pages
102 my @pages = shift->catalog(@_);
103 my @flat = map { @
{$_->{threads
}} } @pages;
104 wantarray ?
@flat : \
@flat
108 my ($self, $board, $threadno, $is_4chan) = @_;
109 $board = $board->{board
} if ref $board;
110 $threadno = $threadno->{no} if ref $threadno;
111 $is_4chan //= (index $self->{url
}, '4cdn.org') >= 0;
112 my $res_or_thread = $is_4chan ?
'thread' : 'res';
114 $self->requestf('%s/%s/%s.json', $board, $res_or_thread, $threadno);
115 my @posts = map { Hash
::Inflator
->new($_) } @
{$result->{posts
}};
116 wantarray ?
@posts : \
@posts
126 WebService::Vichan - API client for 4chan and vichan-based imageboards
130 use WebService::Vichan qw/:all/;
131 my $chan = WebService::Vichan->new(API_4CHAN);
133 my @boards = $chan->boards;
134 say 'Boards on 4chan: ', join ', ', map { $_->board } @boards;
136 my @all_pages_of_wsg = $chan->threads('wsg');
137 my @wsg = @{$all_pages_of_wsg[0]->threads};
138 say 'IDs of threads on the first page of /wsg/: ', join ', ', map { $_->no } @wsg;
140 my @all_threads_of_g = $chan->threads_flat('g');
141 my @posts_in_23rd_thread = $chan->thread('g', $all_threads_of_g[22]);
142 printf "There are %d posts in the 23rd thread of /g/\n", scalar @posts_in_23rd_thread;
143 my $the_post = $posts_in_23rd_thread[1];
144 say 'HTML of the 2nd post in the 23rd thread of /g/: ', $the_post->com;
148 This is an api client for 4chan.org and imageboards that use vichan
149 (such as 8ch.net). It offers the following methods:
151 Note: functions that ordinarily return lists will return arrayrefs if
152 called in scalar context.
156 =item WebService::Vichan->B<new>(I<$url>)
158 Creates a new WebService::Vichan object with the given base URL.
160 Two constants are exported on request by this module: C<API_4CHAN> and
161 C<API_8CHAN>, which represent the base URLs for 4chan.org and 8ch.net.
163 =item $chan->B<boards>
165 Returns a list of available boards. These are blessed
166 imageboard-dependent hashrefs which should at least have the methods
167 C<board> (returning the board code as a string) and C<title>.
169 =item $chan->B<threads>(I<$board>)
171 Takes a board object (or a board code as a string) and returns a list
172 of pages of thread OPs. Each page is a blessed hashref with methods
173 C<page> (the index of the page) and C<threads> (an arrayref of thread
174 OPs on that page). Each thread OP is a blessed hashref which has at
175 least the methods C<no> (the thread number) and C<last_modified>.
177 =item $chan->B<threads_flat>(I<$board>)
179 Same as B<threads> but page information is dropped. Returns a list of
180 thread OPs as described above.
182 =item $chan->B<catalog>(I<$board>)
184 Same as B<threads>, but much more information is returned about each
187 =item $chan->B<catalog_flat>(I<$board>)
189 Same as B<threads_flat>, but much more information is returned about each thread OP.
191 =item $chan->B<thread>(I<$board>, I<$threadno>, [I<$is_4chan>])
193 Takes a board object (or a board code as a string), a thread OP object
194 (or a thread number) and an optional boolean indicating whether to use
195 4chan logic for the request (by default 4chan logic is used if the URL
196 contains C<4cdn.org>).
198 Returns a post object (blessed hashref) with methods as described in
199 the API documentation (see links in the SEE ALSO section).
203 To comply with API usage rules every request is cached for 10 seconds,
204 and requests are rate-limited to one per second. If a method is called
205 less than 1 second after a request has happened, it will sleep before
206 issuing a second request to ensure the rate limitation is followed.
210 L<https://github.com/4chan/4chan-API>,
211 L<https://github.com/vichan-devel/vichan-API/>
215 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
217 =head1 COPYRIGHT AND LICENSE
219 Copyright (C) 2017 by Marius Gavrilescu
221 This library is free software; you can redistribute it and/or modify
222 it under the same terms as Perl itself, either Perl version 5.24.3 or,
223 at your option, any later version of Perl 5 you may have available.
This page took 0.063505 seconds and 4 git commands to generate.