File Coverage

blib/lib/WWW/Challonge.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package WWW::Challonge;
2 1     1   13964 use WWW::Challonge::Tournament;
  0            
  0            
3             use REST::Client;
4             use JSON qw/to_json from_json/;
5              
6             use 5.006;
7             use strict;
8             use warnings;
9              
10             =head1 NAME
11              
12             WWW::Challonge - Perl wrapper for the Challonge API
13              
14             =head1 VERSION
15              
16             Version 0.10
17              
18             =cut
19              
20             our $VERSION = '0.10';
21              
22             =head1 SYNOPSIS
23              
24             Access the Challonge API within Perl. Contains all the functions within the API,
25             as documented L.
26              
27             use WWW::Challonge;
28              
29             my $c = WWW::Challonge->new($api_key)
30             ...
31              
32             =head1 SUBROUTINES/METHODS
33              
34             =head2 new
35              
36             Creates a new C object. Takes in an API key, which is required:
37              
38             my $c = WWW::Challonge->new($api_key);
39              
40             =cut
41              
42             sub new
43             {
44             # Get the API key:
45             my $class = shift;
46             my $key = shift;
47              
48             # Create a REST client to interface Challonge:
49             my $client = REST::Client->new();
50             $client->setHost("https://api.challonge.com/v1");
51              
52             # Try to get some content and check the response code:
53             $client->GET("/tournaments.json?api_key=$key");
54              
55             # Check to see if the API key is valid:
56             if($client->responseCode() eq '401')
57             {
58             # If it isn't, warn the user and exit:
59             print STDERR "Error: Challonge API key is invalid.\n";
60             return undef;
61             }
62              
63             # Otherwise, keep the key and the client in an object and return:
64             my $c = { key => $key, client => $client };
65             bless $c, $class;
66             }
67              
68             =head2 index
69              
70             Returns an arrayref of all C objects owned by the
71             user authenticated with in the 'new' request (the logged in user, so to speak).
72             Takes a number of optional arguments:
73              
74             =over 4
75              
76             =item state
77              
78             Get tournaments based on their progress:
79              
80             =over 4
81              
82             =item all
83              
84             Gets all tournaments regardless of state.
85              
86             =item pending
87              
88             Gets all tournaments that have yet to start.
89              
90             =item in_progress
91              
92             Gets all tournaments that have started but have not finished.
93              
94             =item ended
95              
96             Gets all tournaments that have finished.
97              
98             =back
99              
100             =item type
101              
102             Gets all tournaments of the given type:
103              
104             =over 4
105              
106             =item single_elimination
107              
108             =item double_elimination
109              
110             =item round_robin
111              
112             =item swiss
113              
114             =back
115              
116             =item created_after
117              
118             Gets all the tournaments created after the given date. Can be given as a string
119             (YYYY-MM-DD) or as a C object.
120              
121             =item created_before
122              
123             Gets all the tournaments created before the given date. Can be given as a string
124             (YYYY-MM-DD) or as a C object.
125              
126             =item subdomain
127              
128             Gets all tournaments created under the given subdomian.
129              
130             =back
131              
132             my $tournies = $c->index();
133             my $tournies2 = $c->index({
134             type => "double_elimination",
135             created_after => "2015-03-18",
136             });
137              
138             =cut
139              
140             sub index
141             {
142             my $self = shift;
143             my $options = shift // {};
144              
145             # Get the key and the client:
146             my $key = $self->{key};
147             my $client = $self->{client};
148              
149             # The intial request URL:
150             my $req = "/tournaments.json?api_key=$key";
151              
152             # Loop through the options (if any) and add them on:
153             for my $option(keys %{$options})
154             {
155             # Validate the input:
156             if($option =~ /^state$/)
157             {
158             if($options->{$option} !~ /^all|pending|in_progress|ended$/)
159             {
160             print STDERR "Error: Argument '" . $options->{option} .
161             "' for option '$option' is invalid.";
162             }
163             }
164             elsif($option =~ /^type$/)
165             {
166             if($options->{$option} !~ /^(single|double)_elimination|round_robin|swiss$/)
167             {
168             print STDERR "Error: Argument '" . $options->{option} .
169             "' for option '$option' is invalid.";
170             }
171             }
172             elsif($option =~ /^created_(before|after)$/)
173             {
174             if($options->{$option} !~ /^\d{4}-\d{2}-\d{2}$/)
175             {
176             print STDERR "Error: Argument '" . $options->{option} .
177             "' for option '$option' is invalid.";
178             }
179             }
180             elsif($option =~ /^subdomain$/)
181             {
182             if($options->{$option} !~ /^[a-zA-Z0-9_]*$/)
183             {
184             print STDERR "Error: Argument '" . $options->{option} .
185             "' for option '$option' is invalid.";
186             }
187             }
188             else
189             {
190             print STDERR "Error: Option '$option' is invalid.";
191             return undef;
192             }
193              
194             $req .= "&" . $option . "=" . $options->{$option};
195             }
196              
197             # Make the request:
198             $client->GET($req);
199              
200             # Make a new tournament object for every tourney returned:
201             my @tournaments;
202             for my $tournament(@{from_json($client->responseContent())})
203             {
204             push @tournaments, WWW::Challonge::Tournament->new($tournament,
205             $key, $client);
206             }
207              
208             # Return the array of tournaments:
209             return \@tournaments;
210             }
211              
212             =head2 show
213              
214             Gets a single C object by the given id or URL:
215              
216             my $tourney = $c->show("sample_tournament_1");
217              
218             If the tournament has a subdomain (e.g. test.challonge.com/mytourney), simply
219             specify like so:
220              
221             my $tourney = $c->show("test-mytourney")
222              
223             =cut
224              
225             sub show
226             {
227             my $self = shift;
228             my $url = shift;
229              
230             # Get the key and REST client:
231             my $key = $self->{key};
232             my $client = $self->{client};
233              
234             # Try to get the tournament:
235             $client->GET("/tournaments/$url.json?api_key=$key");
236              
237             # Check for any errors:
238             if($client->responseCode eq '404')
239             {
240             print STDERR "Error: Tournament '$url' not found.\n";
241             return undef;
242             }
243              
244             # Otherwise create a tourney with the object and return it:
245             my $tourney = WWW::Challonge::Tournament->new(
246             from_json($client->responseContent), $key, $client);
247             return $tourney;
248             }
249              
250             =head2 create
251              
252             Creates a new tournament, and returns it as a C
253             object. It takes an hashref of arguments. The name and URL are required, all
254             others are optional.
255              
256             =over 4
257              
258             =item name
259              
260             A string containing the name of the tournament.
261              
262             =item tournament_type
263              
264             A string containing one of the following, detailing the type of tournament.
265              
266             =over 4
267              
268             =item single elimination (default)
269              
270             =item double elimination
271              
272             =item round robin
273              
274             =item swiss
275              
276             =back
277              
278             =item url
279              
280             The url of the tournament, containing only letters, numbers and underscores.
281              
282             =item subdomain
283              
284             The subdomain of the tournament (requires write access to the given subdomain).
285              
286             =item description
287              
288             The description of the tournament to be displayed above the bracket.
289              
290             =item game_name
291              
292             The name of the game or sport being played.
293              
294             =item open_signup
295              
296             True/false. Have Challonge host a sign-up page (otherwise, manually add
297             participants).
298              
299             =item hold_third_place_match
300              
301             True/false. Single elimination only. Hold a match for semifinals losers to
302             determine third place? Default is false.
303              
304             =item pts_for_match_win
305              
306             Decimal (to the nearest tenth). Number of points gained on winning a match.
307             Swiss only. Default is 1.0.
308              
309             =item pts_for_match_tie
310              
311             Decimal (to the nearest tenth). Number of points gained on drawing a match.
312             Swiss only. Default is 0.5.
313              
314             =item pts_for_game_win
315              
316             Decimal (to the nearest tenth). Number of points gained on winning a single
317             game within a match. Swiss only. Default is 0.0.
318              
319             =item pts_for_game_tie
320              
321             Decimal (to the nearest tenth). Number of points gained on drawing a single
322             game within a match. Swiss only. Default is 0.0.
323              
324             =item pts_for_bye
325              
326             Decimal (to the nearest tenth). Number of points gained on getting a bye.
327             Swiss only. Default is 1.0.
328              
329             =item swiss_rounds
330              
331             Integer. Number of swiss rounds to play. Swiss only. It is recommended that
332             the number of rounds is limited to no more than two thirds of the number of
333             players, otherwise an impossible pairing situation may occur and the
334             tournament may end prematurely.
335              
336             =item ranked_by
337              
338             How the tournament is ranked. Can be one of the following.
339              
340             =over 4
341              
342             =item match wins
343              
344             =item game wins
345              
346             =item points scored
347              
348             =item points difference
349              
350             =item custom
351              
352             =back
353              
354             =item rr_pts_for_match_win
355              
356             Decimal (to the nearest tenth). Number of points gained by winning a match.
357             Round Robin 'custom' only. Default is 1.0.
358              
359             =item rr_pts_for_match_tie
360              
361             Decimal (to the nearest tenth). Number of points gained by drawing a match.
362             Round Robin 'custom' only. Default is 0.5.
363              
364             =item rr_pts_for_game_win
365              
366             Decimal (to the nearest tenth). Number of points gained by winning a single
367             game within a match. Round Robin 'custom' only. Default is 0.0.
368              
369             =item rr_pts_for_game_tie
370              
371             Decimal (to the nearest tenth). Number of points gained by drawing a single
372             game within a match. Round Robin 'custom' only. Default is 0.0.
373              
374             =item accept_attachments
375              
376             True/false. Allow match attachment uploads. Default is false.
377              
378             =item hide_forum
379              
380             True/false. Hide the forum tab on your Challonge page. Default is false.
381              
382             =item show_rounds
383              
384             True/false. Label each round about the bracket. Single and double elimination
385             only. Default is false.
386              
387             =item private
388              
389             True/false. Hide this tournament from the public browsable index and your
390             profile. Default is false.
391              
392             =item notify_users_when_matches_open
393              
394             True/false. Send registered Challonge users an email when matches open up
395             for them. Default is false.
396              
397             =item nofity_users_when_the_tournament_ends
398              
399             True/false. Send registered Challonge users an email with the results when
400             the tournament ends. Default is false.
401              
402             =item sequential_pairings
403              
404             True/false. Instead of following traditional seeding rules, make the pairings
405             go straight down the list of participants. For example, the first match will
406             be the first seed versus the second. Default is false.
407              
408             =item signup_cap
409              
410             Integer. The maximum number of participants. Any additional participants will
411             go on a waiting list.
412              
413             =item start_at
414              
415             DateTime. The planned time to start the tournament. Timezone defaults to
416             Eastern (EST).
417              
418             =item check_in_duration
419              
420             Integer. The length of the check-in window in minutes.
421              
422             =back
423              
424             my $tournament = $c->create({
425             name => "sample tournament",
426             url => "sample_tournament_1",
427             type => "double elimination"
428             });
429              
430             =cut
431              
432             sub create
433             {
434             my $self = shift;
435             my $args = shift;
436              
437             # Get the key and REST client:
438             my $key = $self->{key};
439             my $client = $self->{client};
440              
441             # Fail if name and URL aren't given:
442             if((! defined $args->{name}) && (! defined $args->{url}))
443             {
444             print STDERR "Error: Name and URL are required to create a ",
445             "tournament.\n";
446             return undef;
447             }
448              
449             # Check the arguments and values are valid:
450             return undef unless(WWW::Challonge::Tournament::__args_are_valid($args));
451              
452             # Add in the API key and convert to a POST request:
453             my $params = { api_key => $key, tournament => $args };
454              
455             # Now we have all the arguments validated, send the POST request:
456             $client->POST("/tournaments.json", to_json($params),
457             { "Content-Type" => 'application/json' });
458              
459             # Check for any errors:
460             if($client->responseCode >= 300)
461             {
462             my $error = from_json($client->responseContent)->{errors}->[0];
463             if($error =~ /taken/)
464             {
465             print STDERR "Error: URL '", $args->{url}, "' is already taken\n";
466             }
467             return undef;
468             }
469              
470             # Otherwise, make a tournament object and return it:
471             my $t = WWW::Challonge::Tournament->new(
472             from_json($client->responseContent), $key, $client);
473             return $t;
474             }
475              
476             =head1 AUTHOR
477              
478             Alex Kerr, C<< >>
479              
480             =head1 BUGS
481              
482             Please report any bugs or feature requests to C, or through
483             the web interface at L. I will be notified, and then you'll
484             automatically be notified of progress on your bug as I make changes.
485              
486             =head1 SUPPORT
487              
488             You can find documentation for this module with the perldoc command.
489              
490             perldoc WWW::Challonge
491              
492             You can also look for information at:
493              
494             =over 4
495              
496             =item * RT: CPAN's request tracker (report bugs here)
497              
498             L
499              
500             =item * AnnoCPAN: Annotated CPAN documentation
501              
502             L
503              
504             =item * CPAN Ratings
505              
506             L
507              
508             =item * Search CPAN
509              
510             L
511              
512             =back
513              
514             =head1 SEE ALSO
515              
516             =over 4
517              
518             =item L
519              
520             =item L
521              
522             =item L
523              
524             =back
525              
526             =head1 ACKNOWLEDGEMENTS
527              
528             Everyone on the L team for making such a great
529             service.
530              
531             =head1 LICENSE AND COPYRIGHT
532              
533             Copyright 2015 Alex Kerr.
534              
535             This program is free software; you can redistribute it and/or modify it
536             under the terms of the the Artistic License (2.0). You may obtain a
537             copy of the full license at:
538              
539             L
540              
541             Any use, modification, and distribution of the Standard or Modified
542             Versions is governed by this Artistic License. By using, modifying or
543             distributing the Package, you accept this license. Do not use, modify,
544             or distribute the Package, if you do not accept this license.
545              
546             If your Modified Version has been derived from a Modified Version made
547             by someone other than you, you are nevertheless required to ensure that
548             your Modified Version complies with the requirements of this license.
549              
550             This license does not grant you the right to use any trademark, service
551             mark, tradename, or logo of the Copyright Holder.
552              
553             This license includes the non-exclusive, worldwide, free-of-charge
554             patent license to make, have made, use, offer to sell, sell, import and
555             otherwise transfer the Package with respect to any patent claims
556             licensable by the Copyright Holder that are necessarily infringed by the
557             Package. If you institute patent litigation (including a cross-claim or
558             counterclaim) against any party alleging that the Package constitutes
559             direct or contributory patent infringement, then this Artistic License
560             to you shall terminate on the date that such litigation is filed.
561              
562             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
563             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
564             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
565             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
566             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
567             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
568             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
569             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
570              
571             =cut
572              
573             1; # End of WWW::Challonge