File Coverage

blib/lib/WWW/Challonge/Tournament.pm
Criterion Covered Total %
statement 218 233 93.5
branch 73 106 68.8
condition 4 6 66.6
subroutine 23 23 100.0
pod 14 14 100.0
total 332 382 86.9


line stmt bran cond sub pod time code
1             package WWW::Challonge::Tournament;
2              
3 6     6   117 use 5.010;
  6         16  
  6         248  
4 6     6   26 use strict;
  6         9  
  6         155  
5 6     6   29 use warnings;
  6         8  
  6         130  
6 6     6   2347 use WWW::Challonge::Participant;
  6         11  
  6         183  
7 6     6   2557 use WWW::Challonge::Match;
  6         14  
  6         187  
8 6     6   34 use Carp qw/carp croak/;
  6         8  
  6         273  
9 6     6   26 use JSON qw/to_json from_json/;
  6         8  
  6         23  
10              
11             sub __is_kill;
12             sub __args_are_valid;
13              
14             =head1 NAME
15              
16             WWW::Challonge::Tournament - A class representing a single Challonge tournament.
17              
18             =head1 VERSION
19              
20             Version 1.00
21              
22             =cut
23              
24             our $VERSION = '1.00';
25              
26             =head1 SUBROUTINES/METHODS
27              
28             =head2 new
29              
30             Takes a hashref representing the tournament, the API key and the REST client
31             and turns it into an object. This is mostly used by the module itself, to
32             create a new tournament see L.
33              
34             my $t = WWW::Challonge::Tournament->new($tournament, $key, $client);
35              
36             =cut
37              
38             sub new
39             {
40 31     31 1 3645 my $class = shift;
41 31         46 my $tournament = shift;
42 31         39 my $key = shift;
43 31         42 my $client = shift;
44              
45 31         124 my $t =
46             {
47             alive => 1,
48             client => $client,
49             tournament => $tournament->{tournament},
50             key => $key,
51             };
52 31         125 bless $t, $class;
53             }
54              
55             =head2 update
56              
57             Updates specific attributes of a tournament. For a full list, see
58             L. Unlike that method, however, all of the arguments
59             are optional.
60              
61             $t->update({
62             name => "sample_tournament_2",
63             type => "swiss",
64             });
65              
66             =cut
67              
68             sub update
69             {
70 5     5 1 2503 my $self = shift;
71 5         7 my $args = shift;
72              
73             # Do not operate on a dead tournament:
74 5 100       20 return __is_kill unless($self->{alive});
75              
76             # Die on no errors:
77 4 100       122 croak "No arguments given" unless(defined $args);
78              
79             # Get the key, REST client and tournament url:
80 3         6 my $key = $self->{key};
81 3         5 my $client = $self->{client};
82 3         8 my $url = $self->{tournament}->{url};
83 3         7 my $HOST = $WWW::Challonge::HOST;
84              
85             # Check the arguments and values are valid:
86 3 50       8 return undef unless(WWW::Challonge::Tournament::__args_are_valid($args));
87              
88             # Add the API key and put everything else in a 'tournament' hash:
89 2         6 my $params = { api_key => $key, tournament => $args };
90              
91             # Make the PUT request:
92 2         21 my $response = $client->request(WWW::Challonge::__json_request(
93             "$HOST/tournaments/$url.json", "PUT", $params));
94              
95             # Check for any errors:
96 2 50       2080 WWW::Challonge::__handle_error $response if($response->is_error);
97              
98 2         25 return 1;
99             }
100              
101             =head2 destroy
102              
103             Deletes the tournament from the user's account. There is no undo, so use with
104             care!
105              
106             $t->destroy;
107              
108             # $t still contains the tournament, but any future operations will fail:
109             $t->update({ name => "sample_tournament_2" }); # ERROR!
110              
111             =cut
112              
113             sub destroy
114             {
115 2     2 1 369 my $self = shift;
116              
117             # Do not operate on a dead tournament:
118 2 100       15 return __is_kill unless($self->{alive});
119              
120             # Get the key, REST client and tournament URL:
121 1         3 my $key = $self->{key};
122 1         2 my $client = $self->{client};
123 1         4 my $url = $self->{tournament}->{url};
124 1         2 my $HOST = $WWW::Challonge::HOST;
125              
126             # Make the DELETE call:
127 1         16 my $response = $client->delete("$HOST/tournaments/$url.json?api_key=$key");
128              
129             # Check for any errors:
130 1 50       833 WWW::Challonge::__handle_error $response if($response->is_error);
131              
132             # Set the tournament to dead:
133 1         9 $self->{alive} = 0;
134              
135 1         10 return 1;
136             }
137              
138             =head2 process_check_ins
139              
140             This should be invoked after a tournament's check-in window closes, but before
141             the tournament is started. It then does the following:
142              
143             =over 4
144              
145             =item 1
146              
147             Marks participants who have not checked in as inactive.
148              
149             =item 2
150              
151             Moves inactive participants to the bottom seeds.
152              
153             =item 3
154              
155             Transitions the tournament state from "checking_in" to "checked_in".
156              
157             =back
158              
159             $t->process_check_ins;
160              
161             =cut
162              
163             sub process_check_ins
164             {
165 4     4 1 450 my $self = shift;
166              
167             # Do not operate on a dead tournament:
168 4 100       21 return __is_kill unless($self->{alive});
169              
170             # Get the key, REST client and tournament URL:
171 3         10 my $key = $self->{key};
172 3         5 my $client = $self->{client};
173 3         10 my $url = $self->{tournament}->{url};
174 3         8 my $HOST = $WWW::Challonge::HOST;
175              
176             # Send the API key:
177 3         9 my $params = { api_key => $key };
178              
179             # Make the POST call:
180 3         24 my $response = $client->request(WWW::Challonge::__json_request(
181             "$HOST/tournaments/$url/process_check_ins.json", "POST", $params));
182              
183 3 100       2455 WWW::Challonge::__handle_error $response if($response->is_error);
184              
185 2         23 return 1;
186             }
187              
188             =head2 abort_check_in
189              
190             Aborts the check-in process if the tournament's status is currently
191             "checking_in" or "checked_in". This is useful as you cannot edit the
192             tournament's start time during this state. It does the following:
193              
194             =over 4
195              
196             =item 1
197              
198             Makes all participants active and clears their "checked_in_at" times.
199              
200             =item 2
201              
202             Sets the tournament state from "checking_in" or "checked_in" to "pending".
203              
204             =back
205              
206             $t->abort_check_in;
207              
208             =cut
209              
210             sub abort_check_in
211             {
212 2     2 1 391 my $self = shift;
213              
214             # Do not operate on a dead tournament:
215 2 100       8 return __is_kill unless($self->{alive});
216              
217             # Get the key, REST client and tournament URL:
218 1         3 my $key = $self->{key};
219 1         2 my $client = $self->{client};
220 1         2 my $url = $self->{tournament}->{url};
221 1         2 my $HOST = $WWW::Challonge::HOST;
222              
223             # Send the API key:
224 1         2 my $params = { api_key => $key };
225              
226             # Make the POST call:
227 1         6 my $response = $client->request(WWW::Challonge::__json_request(
228             "$HOST/tournaments/$url/abort_check_in.json", "POST", $params));
229              
230             # Check for any errors:
231 1 50       776 WWW::Challonge::__handle_error $response if($response->is_error);
232              
233 1         13 return 1;
234             }
235              
236             =head2 start
237              
238             Starts a tournament, opening up matches for score reporting. The tournament
239             must have at least 2 participants. If successful, sets the state of the
240             tournament to "underway".
241              
242             $t->start;
243              
244             =cut
245              
246             sub start
247             {
248 2     2 1 357 my $self = shift;
249              
250             # Do not operate on a dead tournament:
251 2 100       9 return __is_kill unless($self->{alive});
252              
253             # Get the key, REST client and tournament URL:
254 1         3 my $key = $self->{key};
255 1         2 my $client = $self->{client};
256 1         2 my $url = $self->{tournament}->{url};
257 1         2 my $HOST = $WWW::Challonge::HOST;
258              
259             # Send the API key:
260 1         2 my $params = { api_key => $key };
261              
262             # Make the POST call:
263 1         7 my $response = $client->request(WWW::Challonge::__json_request(
264             "$HOST/tournaments/$url/start.json", "POST", $params));
265              
266             # Check for any errors:
267 1 50       754 WWW::Challonge::__handle_error $response if($response->is_error);
268              
269 1         12 return 1;
270             }
271              
272             =head2 finalize
273              
274             Finalises a tournament that has had all match scores submitted, rendering the
275             results permenant. If successful, it sets the state to "complete".
276              
277             $t->finalize;
278              
279             =cut
280              
281             sub finalize
282             {
283 2     2 1 365 my $self = shift;
284              
285             # Do not operate on a dead tournament:
286 2 100       9 return __is_kill unless($self->{alive});
287              
288             # Get the key, REST client and tournament URL:
289 1         2 my $key = $self->{key};
290 1         1 my $client = $self->{client};
291 1         3 my $url = $self->{tournament}->{url};
292 1         2 my $HOST = $WWW::Challonge::HOST;
293              
294             # Send the API key:
295 1         2 my $params = { api_key => $key };
296              
297             # Make the POST call:
298 1         7 my $response = $client->request(WWW::Challonge::__json_request(
299             "$HOST/tournaments/$url/finalize.json", "POST", $params));
300              
301             # Check for any errors:
302 1 50       774 WWW::Challonge::__handle_error $response if($response->is_error);
303              
304 1         12 return 1;
305             }
306              
307             =head2 reset
308              
309             Resets an "in_progress" tournament, deleting all match records. You can add,
310             remove or edit users before starting again. Sets the state to "pending".
311              
312             $t->reset;
313              
314             =cut
315              
316             sub reset
317             {
318 2     2 1 439 my $self = shift;
319              
320             # Do not operate on a dead tournament:
321 2 100       15 return __is_kill unless($self->{alive});
322              
323             # Get the key, REST client and tournament URL:
324 1         2 my $key = $self->{key};
325 1         2 my $client = $self->{client};
326 1         3 my $url = $self->{tournament}->{url};
327 1         2 my $HOST = $WWW::Challonge::HOST;
328              
329             # Send the API key:
330 1         2 my $params = { api_key => $key };
331              
332             # Make the POST call:
333 1         7 my $response = $client->request(WWW::Challonge::__json_request(
334             "$HOST/tournaments/$url/reset.json", "POST", $params));
335              
336             # Check for any errors:
337 1 50       830 WWW::Challonge::__handle_error $response if($response->is_error);
338              
339 1         12 return 1;
340             }
341              
342             =head2 attributes
343              
344             Gets all the attributes of the tournament in a hashref. Contains the following
345             fields.
346              
347             =over 4
348              
349             =item accepting_predictions
350              
351             =item accept_attachments
352              
353             =item allow_participant_match_reporting
354              
355             =item anonymous_voting
356              
357             =item category
358              
359             =item check_in_duration
360              
361             =item completed_at
362              
363             =item created_at
364              
365             =item created_by_api
366              
367             =item credit_capped
368              
369             =item description
370              
371             =item description_source
372              
373             =item full_challonge_url
374              
375             =item game_id
376              
377             =item game_name
378              
379             =item group_stages_enabled
380              
381             =item group_stages_were_started
382              
383             =item hide_forum
384              
385             =item hide_seeds
386              
387             =item hold_third_place_match
388              
389             =item id
390              
391             =item live_image_url
392              
393             =item max_predictions_per_user
394              
395             =item name
396              
397             =item notify_users_when_match_opens
398              
399             =item notify_users_when_the_tournament_ends
400              
401             =item open_signup
402              
403             =item participants_count
404              
405             =item participants_locked
406              
407             =item participants_swappable
408              
409             =item prediction_method
410              
411             =item predictions_opened_at
412              
413             =item private
414              
415             =item progress_meter
416              
417             =item pts_for_bye
418              
419             =item pts_for_game_tie
420              
421             =item pts_for_game_win
422              
423             =item pts_for_match_tie
424              
425             =item pts_for_match_win
426              
427             =item quick_advance
428              
429             =item ranked_by
430              
431             =item review_before_finalizing
432              
433             =item require_score_agreement
434              
435             =item rr_pts_for_game_tie
436              
437             =item rr_pts_for_game_win
438              
439             =item rr_pts_for_match_tie
440              
441             =item rr_pts_for_match_win
442              
443             =item sequential pairings
444              
445             =item show_rounds
446              
447             =item signup_cap
448              
449             =item sign_up_url
450              
451             =item start_at
452              
453             =item started_at
454              
455             =item started_checking_in_at
456              
457             =item state
458              
459             =item swiss_rounds
460              
461             =item subdomain
462              
463             =item teams
464              
465             =item team_convertable
466              
467             =item tie_breaks
468              
469             =item tournament_type
470              
471             =item updated_at
472              
473             =item url
474              
475             =back
476              
477             my $attr = $t->attributes;
478             print $attr->{name}, "\n";
479              
480             =cut
481              
482             sub attributes
483             {
484 7     7 1 1822 my $self = shift;
485              
486             # Do not operate on a dead tournament:
487 7 100       32 return __is_kill unless($self->{alive});
488              
489             # Get the key, REST client and url:
490 6         13 my $key = $self->{key};
491 6         6 my $client = $self->{client};
492 6         19 my $url = $self->{tournament}->{url};
493 6         9 my $HOST = $WWW::Challonge::HOST;
494              
495             # Get the most recent version:
496 6         37 my $response = $client->get(
497             "$HOST/tournaments/$url.json?api_key=$key");
498              
499             # Check for any errors:
500 6 50       4993 WWW::Challonge::__handle_error $response if($response->is_error);
501              
502             # Save the most recent version and return it:
503 6         51 $self->{tournament} = from_json($response->decoded_content)->{tournament};
504              
505 6         1000 return $self->{tournament};
506             }
507              
508             =head2 participants
509              
510             Returns an arrayref of C objects for every
511             participant in the tourney.
512              
513             my $p = $t->participants;
514             for my $participant(@{$p})
515             {
516             ...
517              
518             =cut
519              
520             sub participants
521             {
522 2     2 1 357 my $self = shift;
523              
524             # Do not operate on a dead tournament:
525 2 100       11 return __is_kill unless($self->{alive});
526              
527             # Get the key, REST client and url:
528 1         4 my $key = $self->{key};
529 1         2 my $client = $self->{client};
530 1         5 my $url = $self->{tournament}->{url};
531 1         2 my $HOST = $WWW::Challonge::HOST;
532              
533             # Make the GET request:
534 1         10 my $response = $client->get(
535             "$HOST/tournaments/$url/participants.json?api_key=$key");
536              
537             # Check for any errors:
538 1 50       999 WWW::Challonge::__handle_error $response if($response->is_error);
539              
540             # If not, make an object for every participant:
541 1         8 my $participants = [];
542 1         2 for my $participant(@{from_json($response->decoded_content)})
  1         3  
543             {
544 4         175 push @{$participants}, WWW::Challonge::Participant->new($participant,
  4         14  
545             $key, $client);
546             }
547 1         4 return $participants;
548             }
549              
550             =head2 participant
551              
552             Returns a single C object representing the
553             participant with the given unique ID.
554              
555             my $p = $t->participant(24279875);
556              
557             =cut
558              
559             sub participant
560             {
561 4     4 1 1089 my $self = shift;
562 4         6 my $participant = shift;
563              
564             # Do not operate on a dead tournament:
565 4 100       14 return __is_kill unless($self->{alive});
566              
567             # Die on no arguments:
568 3 100       124 croak "No arguments given" unless(defined $participant);
569              
570             # Get the key, REST client and url:
571 2         4 my $key = $self->{key};
572 2         2 my $client = $self->{client};
573 2         6 my $url = $self->{tournament}->{url};
574 2         4 my $HOST = $WWW::Challonge::HOST;
575              
576             # Make the GET request:
577 2         13 my $response = $client->get(
578             "$HOST/tournaments/$url/participants/$participant.json?api_key=$key");
579              
580             # Check for any errors:
581 2 100       2129 WWW::Challonge::__handle_error $response if($response->is_error);
582              
583             # If so, create an object and return it:
584 1         11 my $p = WWW::Challonge::Participant->new(
585             from_json($response->decoded_content), $key, $client);
586 1         5 return $p;
587             }
588              
589             =head2 new_participant
590              
591             Adds a new participant to the tournament, and if successful returns the newly
592             created C object. The possible arguments are as
593             follows.
594              
595             =over 4
596              
597             =item name
598              
599             The name of the participant. Required unless I or I
600             are provided. Must be unique within the tournament.
601              
602             =item challonge_username
603              
604             If the participant has a valid Challonge account, providing a name will send
605             them an invite to join the tournament.
606              
607             =item email
608              
609             If the email is attached to a valid Challonge account, it will invite them to
610             join the tournament. If not, the 'new-user-email' attribute will be set, and
611             an email will be sent to invite the person to join Challonge.
612              
613             =item seed
614              
615             Integer. The participant's new seed. Must be between 1 and the new number of
616             participants. Overwriting an existing seed will bump up the other participants.
617             If none is given, the participant will be given the lowest possible seed (the
618             bottom).
619              
620             =item misc
621              
622             Miscellaneous notes on a player only accessible via the API. Maximum 255
623             characters.
624              
625             =back
626              
627             my $p = $t->new_participant({
628             name => "test",
629             seed => 4
630             });
631              
632             =cut
633              
634             sub new_participant
635             {
636 16     16 1 10627 my $self = shift;
637 16         23 my $args = shift;
638              
639             # Do not operate on a dead tournament:
640 16 100       49 return __is_kill unless($self->{alive});
641              
642             # Get the key, REST client and url:
643 15         26 my $key = $self->{key};
644 15         20 my $client = $self->{client};
645 15         34 my $url = $self->{tournament}->{url};
646 15         23 my $HOST = $WWW::Challonge::HOST;
647              
648             # Fail if name or challonge_username or email is not provided:
649 15 50 66     60 unless((defined $args->{name}) || (defined $args->{challonge_username}) ||
      66        
650             (defined $args->{email}))
651             {
652 2         235 croak "Name, email or Challonge username are required to create a new ".
653             "participant.\n";
654 0         0 return undef;
655             }
656              
657             # Check the arguments and values are valid:
658 13 50       46 return undef unless(WWW::Challonge::Participant::__args_are_valid($args));
659              
660             # Add in the API key and convert to a POST request:
661 13         37 my $params = { api_key => $key, participant => $args };
662              
663             # Now we have all the arguments validated, send the POST request:
664 13         83 my $response = $client->request(WWW::Challonge::__json_request(
665             "$HOST/tournaments/$url/participants.json", "POST", $params));
666              
667             # Check for any errors:
668 13 100       12877 WWW::Challonge::__handle_error $response if($response->is_error);
669              
670             # If not, create an object and return it:
671 10         110 my $p = WWW::Challonge::Participant->new(
672             from_json($response->decoded_content), $key, $client);
673 10         60 return $p;
674             }
675              
676             =head2 matches
677              
678             Returns an arrayref of C objects for every
679             match in the tourney. The tournament must be in progress before this will
680             return anything useful.
681              
682             my $m = $t->matches;
683             for my $match(@{$m})
684             {
685             ...
686              
687             =cut
688              
689             sub matches
690             {
691 4     4 1 384 my $self = shift;
692              
693             # Do not operate on a dead tournament:
694 4 100       23 return __is_kill unless($self->{alive});
695              
696             # Get the key, REST client and url:
697 3         6 my $key = $self->{key};
698 3         8 my $client = $self->{client};
699 3         7 my $url = $self->{tournament}->{url};
700 3         6 my $HOST = $WWW::Challonge::HOST;
701              
702             # Make the GET request:
703 3         22 my $response = $client->get(
704             "$HOST/tournaments/$url/matches.json?api_key=$key");
705              
706             # Check for any errors:
707 3 50       2722 WWW::Challonge::__handle_error $response if($response->is_error);
708              
709             # If so, make an object for every participant:
710 3         24 my $matches = [];
711 3         7 for my $match(@{from_json($response->decoded_content)})
  3         16  
712             {
713 18         622 push @{$matches}, WWW::Challonge::Match->new($match, $key,
  18         56  
714             $client);
715             }
716 3         21 return $matches;
717             }
718              
719             =head2 match
720              
721             Returns a single C object representing the match with
722             the given unique ID.
723              
724             my $m = $t->match(24279875);
725              
726             =cut
727              
728             sub match
729             {
730 4     4 1 1039 my $self = shift;
731 4         7 my $match = shift;
732              
733             # Do not operate on a dead tournament:
734 4 100       13 return __is_kill unless($self->{alive});
735              
736             # Die on no arguments:
737 3 100       87 croak "No arguments given" unless(defined $match);
738              
739             # Get the key, REST client and url:
740 2         3 my $key = $self->{key};
741 2         2 my $client = $self->{client};
742 2         5 my $url = $self->{tournament}->{url};
743 2         5 my $HOST = $WWW::Challonge::HOST;
744              
745             # Make the GET request:
746 2         11 my $response = $client->get(
747             "$HOST/tournaments/$url/matches/$match.json?api_key=$key");
748              
749             # Check for any errors:
750 2 100       2511 WWW::Challonge::__handle_error $response if($response->is_error);
751              
752             # If so, create an object and return it:
753 1         10 my $m = WWW::Challonge::Match->new(from_json($response->decoded_content),
754             $key, $client);
755 1         4 return $m;
756             }
757              
758             =head2 __is_kill
759              
760             Returns an error explaining that the current tournament has been destroyed and
761             returns undef, used so a function doesn't attempt to operate on a tournament
762             that has been successfully destroyed.
763              
764             =cut
765              
766             sub __is_kill
767             {
768 13     13   1174 croak "Tournament has been destroyed";
769             }
770              
771             =head2 __args_are_valid
772              
773             Checks if the passed arguments and values are valid for creating or updating
774             a tournament.
775              
776             =cut
777              
778             sub __args_are_valid
779             {
780 20     20   3501 my $args = shift;
781              
782             # The possible parameters, grouped together by the kind of input they take.
783 20         171 my %valid_args = (
784             string => [
785             "name",
786             "tournament_type",
787             "url",
788             "subdomain",
789             "description",
790             "game_name",
791             "ranked_by",
792             ],
793             integer => [
794             "swiss_rounds",
795             "signup_cap",
796             "check_in_duration",
797             ],
798             decimal => [
799             "pts_for_match_win",
800             "pts_for_match_tie",
801             "pts_for_game_win",
802             "pts_for_game_tie",
803             "pts_for_bye",
804             "rr_pts_for_match_win",
805             "rr_pts_for_match_tie",
806             "rr_pts_for_game_win",
807             "rr_pts_for_game_tie",
808             ],
809             bool => [
810             "open_signup",
811             "hold_third_place_match",
812             "accept_attachments",
813             "hide_forum",
814             "show_rounds",
815             "private",
816             "notify_users_when_matches_open",
817             "notify_users_when_the_tournament_ends",
818             "sequential_pairings",
819             ],
820             datetime => [
821             "start_at"
822             ],
823             );
824              
825             # Validate the inputs:
826 20         32 for my $arg(@{$valid_args{string}})
  20         60  
827             {
828 140 100       272 next unless(defined $args->{$arg});
829             # Most of the string-based arguments require individual validation
830             # based on what they are:
831 23 100       109 if($arg =~ /^name$/)
    50          
    50          
    0          
832             {
833 12 50       41 if(length $args->{$arg} > 60)
834             {
835 0         0 croak "Name '" . $args->{$arg} . " is longer than 60 characters";
836             }
837             }
838             elsif($arg =~ /^tournament_type$/)
839             {
840 0 0       0 if($args->{$arg} !~ /^((single|double) elimination)|(round robin)|
841             (swiss)$/i)
842             {
843 0         0 croak "Value '" . $args->{$arg} . "' is invalid for argument '".
844             $arg . "'";
845             }
846             }
847             elsif($arg =~ /^url$/)
848             {
849 11 50       48 if($args->{$arg} !~ /^[a-zA-Z0-9_]*$/)
850             {
851 0         0 croak "Value '" . $args->{$arg} . "' is not a valid URL";
852             }
853             }
854             elsif($arg =~ /^ranked_by$/)
855             {
856 0 0       0 if($args->{$arg} !~ /^((match|game) wins)|
857             (points (scored|difference))|custom/i)
858             {
859 0         0 croak "Value '" . $args->{$arg} . "' is invalid for argument '".
860             $arg . "'";
861             }
862             }
863             }
864 20         30 for my $arg(@{$valid_args{integer}})
  20         36  
865             {
866 58 100       124 next unless(defined $args->{$arg});
867             # Make sure the argument is an integer:
868 5 100       37 if($args->{$arg} !~ /^\d*$/)
869             {
870 1         115 croak "Value '" . $args->{$arg} . "' is not a valid integer for " .
871             "argument '" . $arg . "'";
872             }
873             }
874 19         26 for my $arg(@{$valid_args{decimal}})
  19         37  
875             {
876 171 50       328 next unless(defined $args->{$arg});
877             # Make sure the argument is an integer or decimal:
878 0 0       0 if($args->{$arg} !~ /^\d*\.?\d*$/)
879             {
880 0         0 croak "Value '" . $args->{$arg} . "' is not a valid decimal for " .
881             "argument '" . $arg . "'";
882             }
883             else
884             {
885 0         0 $args->{$arg} = sprintf("%.1f", $args->{$arg});
886             }
887             }
888 19         29 for my $arg(@{$valid_args{boolean}})
  19         56  
889             {
890 0 0       0 next unless(defined $args->{$arg});
891             # Make sure the argument is true or false:
892 0 0       0 if($args->{$arg} !~ /^(true|false)$/i)
893             {
894 0         0 croak "Value '", $args->{$arg}, "' is not valid for argument '" .
895             $arg . "'. It should be 'true' or 'false'";
896             }
897             }
898 19         23 for my $arg(@{$valid_args{datetime}})
  19         33  
899             {
900 19 100       49 next unless(defined $args->{$arg});
901              
902             # Check if we have a DateTime object:
903 10 50       17 eval { $args->{$arg}->isa("DateTime") } or my $at = $@;
  10         89  
904              
905             # If so, get the ISO8601 string:
906 10 50       128 if($at)
    50          
907             {
908 0         0 $args->{$arg} = $args->{$arg}->iso8601;
909             }
910             # If not make sure the argument is a valid datetime:
911             elsif($args->{$arg} !~ /
912             ^\d{4}- # The year, mandatory in all cases
913             (?:
914             (?:
915             \d{2}-\d{2} # Month and day
916             (?:
917             T\d{2}:\d{2}:\d{2} # Hours, minutes, seconds
918             (?:
919             (?:
920             \+\d{2}:\d{2} # Timezone
921             )
922             |
923             (?:
924             Z # UTC
925             )
926             )
927             )?
928             )
929             |
930             (?:
931             W\d{2} # Week
932             (?:
933             -\d # Date with week number
934             )?
935             )
936             |
937             (?:
938             \d{3} # Ordinal date
939             )
940             )
941             $
942             /x)
943             {
944 0         0 croak "Value '", $args->{$arg}, "' is not a valid datetime for " .
945             "argument '" . $arg . "'";
946             }
947             }
948              
949             # Finally, check if there are any unrecognised arguments, but just ignore
950             # them instead of erroring out:
951 19         43 my @accepted_inputs = (
952 19         31 @{$valid_args{string}},
953 19         25 @{$valid_args{integer}},
954 19         24 @{$valid_args{decimal}},
955 19         78 @{$valid_args{bool}},
956 19         23 @{$valid_args{datetime}}
957             );
958 19         26 my $is_valid = 0;
959 19         16 for my $arg(keys %{$args})
  19         56  
960             {
961 37         47 for my $valid_arg(@accepted_inputs)
962             {
963 375 100       610 if($arg eq $valid_arg)
964             {
965 37         36 $is_valid = 1;
966 37         44 last;
967             }
968             }
969 37 50       56 carp "Ignoring unknown argument '" . $arg . "'" unless($is_valid);
970 37         53 $is_valid = 0;
971             }
972 19         129 return 1;
973             }
974              
975             =head1 AUTHOR
976              
977             Alex Kerr, C<< >>
978              
979             =head1 BUGS
980              
981             Please report any bugs or feature requests to C, or through
982             the web interface at L. I will be notified, and then you'll
983             automatically be notified of progress on your bug as I make changes.
984              
985             =head1 SUPPORT
986              
987             You can find documentation for this module with the perldoc command.
988              
989             perldoc WWW::Challonge::Tournament
990              
991             You can also look for information at:
992              
993             =over 4
994              
995             =item * RT: CPAN's request tracker (report bugs here)
996              
997             L
998              
999             =item * AnnoCPAN: Annotated CPAN documentation
1000              
1001             L
1002              
1003             =item * CPAN Ratings
1004              
1005             L
1006              
1007             =item * Search CPAN
1008              
1009             L
1010              
1011             =back
1012              
1013             =head1 SEE ALSO
1014              
1015             =over 4
1016              
1017             =item L
1018              
1019             =item L
1020              
1021             =item L
1022              
1023             =item L
1024              
1025             =back
1026              
1027             =head1 ACKNOWLEDGEMENTS
1028              
1029             Everyone on the L team for making such a great
1030             service.
1031              
1032             =head1 LICENSE AND COPYRIGHT
1033              
1034             Copyright 2015 Alex Kerr.
1035              
1036             This program is free software; you can redistribute it and/or modify it
1037             under the terms of the the Artistic License (2.0). You may obtain a
1038             copy of the full license at:
1039              
1040             L
1041              
1042             Any use, modification, and distribution of the Standard or Modified
1043             Versions is governed by this Artistic License. By using, modifying or
1044             distributing the Package, you accept this license. Do not use, modify,
1045             or distribute the Package, if you do not accept this license.
1046              
1047             If your Modified Version has been derived from a Modified Version made
1048             by someone other than you, you are nevertheless required to ensure that
1049             your Modified Version complies with the requirements of this license.
1050              
1051             This license does not grant you the right to use any trademark, service
1052             mark, tradename, or logo of the Copyright Holder.
1053              
1054             This license includes the non-exclusive, worldwide, free-of-charge
1055             patent license to make, have made, use, offer to sell, sell, import and
1056             otherwise transfer the Package with respect to any patent claims
1057             licensable by the Copyright Holder that are necessarily infringed by the
1058             Package. If you institute patent litigation (including a cross-claim or
1059             counterclaim) against any party alleging that the Package constitutes
1060             direct or contributory patent infringement, then this Artistic License
1061             to you shall terminate on the date that such litigation is filed.
1062              
1063             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
1064             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
1065             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
1066             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
1067             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
1068             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
1069             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
1070             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1071              
1072             =cut
1073              
1074             1; # End of WWW::Challonge::Tournament