File Coverage

blib/lib/File/TVShow/Info.pm
Criterion Covered Total %
statement 20 242 8.2
branch 0 116 0.0
condition 0 69 0.0
subroutine 7 47 14.8
pod 29 29 100.0
total 56 503 11.1


line stmt bran cond sub pod time code
1             package File::TVShow::Info;
2              
3 14     14   821969 use 5.10.0;
  14         158  
4 14     14   66 use strict;
  14         26  
  14         253  
5 14     14   57 use warnings;
  14         23  
  14         423  
6 14     14   4581 use File::TVShow::EpisodeName 0.01 qw (@episode_name_patterns);
  14         256  
  14         1595  
7 14     14   4417 use File::TVShow::Networks 0.01 qw(@networks);
  14         201  
  14         1079  
8              
9 14     14   105 use vars qw(@filePatterns);
  14         23  
  14         3338  
10              
11             =head1 NAME
12              
13             File::TVShow::Info - Perl meta data extractor from file name for TV Show file.
14              
15             =head1 VERSION
16              
17             Version 0.01.0.1
18              
19             =cut
20              
21             our $VERSION = '0.01.0.1';
22              
23              
24             =head1 SYNOPSIS
25              
26             This module is intended to identify and extract nformation in the file name of a TV show. These details can then be accessed
27             by calling the relevant methods. It does B attempt to read the contents of the file.
28              
29             Note: This module will be modelled off L created by Behan Webster, but will focus on TV Shows only and with additional features.
30              
31             If the file name is parsed and can not be identified as a TV show then L will return 0.
32              
33             use File::TVShow::Info;
34             my $show = File::TVShow::Info->new('file');
35              
36             =cut
37              
38              
39             @filePatterns = (
40             { # TV Show Support - By Date no Season or Episode
41             # Perl > v5.10
42             re => '(?.*?)[.\s_-](?\d{4})[.\s_-](?\d{1,2})[.\s_-](?\d{1,2})(?:[.\s_-](?.*)|)[.](?(?:[a-z]{3}|[a-z]{2}[0-9]))$',
43              
44             # Perl < v5.10
45             re_compat => '(.*?)[.\s_-](\d{4})[.\s_-](\d{1,2})[.\s_-](\d{1,2})(?:[.\s_-](.*)|)[.]((?:[a-z]{3}|[a-z]{2}[0-9]))$',
46             keys_compat => [qw(filename show_name year month date extra_meta ext)],
47             },
48             { # TV Show Support - SssEee or Season_ss_Episode_ss
49             # Perl > v5.10
50             re => '^(?:(?.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(?\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(?\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(?\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(?\d+))?(?[a-z])?(?:[\/\s._-]*(?[^\/]+?))?[.](?(?:[a-z]{3}|[a-z]{2}[0-9]))$',
51              
52             # Perl < v5.10
53             re_compat => '^(?:(.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(\d+))?([a-z])?(?:[\/\s._-]*([^\/]+?))?[.](?(?:[a-z]{3}|[a-z]{2}[0-9]))$',
54             keys_compat => [qw(show_name season episode endep part subep extra_meta)],
55             },
56             { # TV Show Support - sxee
57             # Perl > v5.10
58             re => '^(?:(?.*?)[\/\s._-]*)?(?\[)?(?\d{1,2})[x\/](?\d{1,2})(?:-(?:\kx)?(?\d{1,2}))?(?()\])(?:[\s._-]*(?[^\/]+?))?[.](?(?:[a-z]{3}|[a-z]{2}[0-9]))$',
59              
60             # Perl < v5.10
61             re_compat => '^(?:(.*?)[\/\s._-]*)?\[?(\d{1,2})[x\/](\d{1,2})(?:-(?:\d{1,2}x)?(\d{1,2}))?\]?(?:[\s._-]*([^\/]+?))?[.](?(?:[a-z]{3}|[a-z]{2}[0-9]))$',
62             keys_compat => [qw(show_name season episode endep extra_meta)],
63             },
64             );
65              
66             =head1 Methods
67              
68             =head2 new
69              
70             Create a Info object to extract meta information from the file name.
71              
72             my $show = File::TVShow::Info->new('file');
73              
74             =cut
75              
76             =head3 Object attributes.
77              
78             Attributes may be accessed through $show->{attribute_name} however methods
79             do exist for all required operations.
80              
81             =over 4
82              
83             =item * show_name:
84             Name of the show.
85              
86             =item * original_show_name:
87             This will contain the show name found in the file name without any modifications.
88             This will only be defined if _isolate_name_year has found a year string
89             within the file name such as name.2019, name.(2019), name 2018, name (2018)
90              
91             =item * season:
92             Show season
93              
94             =item * episode:
95             Show episode
96              
97             =item * episode_name
98              
99             =item * country
100              
101             =item * endep: (Naming under consideration)
102             last Episode number found when file name contains SXXEXXEXX
103              
104             =item * year, month, date:
105             Show date e.g 2019.03.03
106             This can be accessed using the method L
107             Note: year will be defined in two cases.
108             One: show name contains year. show_name.yyyy or
109             Two: File name contains YYYY.MM.DD that are identified by date. These are mutually
110             exclusive and no conflict is expected.
111              
112             =item * source
113              
114             =item * resolution:
115             Show resolution 480p/720p and so on. This will be '' if not found.
116              
117             =item * release_group
118              
119             =item * is_subtitle
120              
121             =item * subtitle_lang
122              
123             =item * ext:
124             File extension
125              
126             =back
127              
128             =cut
129              
130             sub new {
131 0     0 1   my $class = shift;
132 0           my $self = {};
133 0           bless $self, $class;
134             # Set default attributes
135 0           @{$self->{valid_countries}} = qw( US UK KR);
  0            
136              
137             # Read default values
138 0           for my $key (qw(file name season episode part options)) {
139 0 0         last unless defined $_[0];
140 0 0         if (ref $_[0]) {
141             # Use a hashref for values
142 0           while (my ($key, $value) = each %{$_[0]}) {
  0            
143 0           $self->{$key} = $value;
144             }
145             } else {
146 0           $self->{$key} = shift;
147             }
148             }
149              
150 0           $self->{filename} = $self->{file};
151              
152             # Run filename through list of patterns
153 0           for my $pat (@filePatterns) {
154 0 0         if ($] >= 5.010000) {
155 0 0         if ($self->{file} =~ /$pat->{re}/i) {
156             # We have a match we will exit after this loop
157 0           $self->{regex} = $pat->{re};
158 14     14   5250 while (my ($key, $data) = each %-) {
  14         4135  
  14         29736  
  0            
159 0 0 0       $self->{$key} = $data->[0] if defined $data->[0] && !defined $self->{$key};
160             }
161             # We have a match so we are skipping all other @filePatterns
162 0           last;
163             }
164             } else { # No named groups in regexes
165 0           my @matches;
166 0 0         if (@matches = ($self->{file} =~ /$pat->{re_compat}/i)) {
167             #print "MACTHES: ".join(',', @matches)."\n";
168 0           $self->{regex} = $pat->{re_compat};
169 0           my $count = 0;
170 0           foreach my $key (@{$pat->{keys_compat}}) {
  0            
171 0 0         $self->{$key} = $matches[$count] unless defined $self->{$key};
172 0           $count++;
173             }
174 0           last;
175             }
176             }
177             }
178 0           $self->_set_tvshow_organize_name();
179 0           $self->_isolate_name_year();
180 0           $self->_get_resolution();
181 0           $self->_get_network();
182 0           $self->_get_release_group();
183 0           $self->_is_tv_subtitle();
184 0           $self->_get_subtitle_lang();
185 0           $self->_get_country();
186 0           $self->_get_episode_name();
187 0           return $self;
188             }
189              
190             =head2 show_name
191              
192             Return the show name found in the file name.
193              
194             =cut
195              
196             sub show_name {
197              
198 0     0 1   my $self = shift;
199 0           my $attr = 'show_name';
200 0           $self->__get_obj_attr($attr);
201             }
202              
203             =head2 strip_show_name
204              
205             Return show_name after removing string delimiters
206              
207             =cut
208              
209             sub strip_show_name {
210              
211 0     0 1   my $self = shift;
212              
213 0 0         return if !$self->is_tv_show();
214              
215 0 0         return $self->{show_name} if defined $self->{do_not_strip};
216 0           (my $newString = $self->{show_name}) =~ s/[\._-]/ /g;
217 0           return $newString;
218              
219             }
220              
221             =head2 clean_show_name
222              
223             Return complete show name with year and country in brackets if they exist.
224             Also remove any delimiters, replaced with spaces
225              
226             =cut
227              
228             sub clean_show_name {
229              
230 0     0 1   my $self = shift;
231              
232 0 0         return if !$self->is_tv_show();
233              
234 0           my $newString = $self->strip_show_name();
235 0 0         if ($self->has_year()) {
    0          
236 0           $newString .= ' (' . $self->year() . ')';
237             } elsif ($self->has_country()) {
238 0           $newString .= ' (' . $self->country() . ')';
239             }
240 0           return $newString;
241             }
242              
243             =head2 original_show_name
244              
245             Return the original show name.
246              
247             This method will return the orginal show name if original_show_name is defined.
248             This will be defined if show_name contains a year string (YYYY) or YYYY
249              
250             If not defined it will return {show_name}
251              
252             =cut
253              
254             sub original_show_name {
255              
256 0     0 1   my $self = shift;
257              
258 0 0         return $self->{original_show_name} if defined $self->{original_show_name};
259 0           return $self->{show_name};
260             }
261              
262             =head2 season
263              
264             Return the season found in the file name. Return '' if {season} is not defined.
265              
266             =cut
267              
268             sub season {
269              
270 0     0 1   my $self = shift;
271 0           my $attr = 'season';
272 0           $self->__get_obj_attr($attr);
273             }
274              
275             =head2 season_to_int
276              
277             Return season as an integer
278              
279             =cut
280              
281             sub season_to_int {
282              
283 0     0 1   my $self = shift;
284 0 0         return int($self->season()) if defined $self->{season};
285 0           return undef;
286             }
287              
288             =head2 episode
289              
290             Return the episode found in the file name. Return '' if {episode} is not defined.
291              
292             =cut
293              
294             sub episode {
295              
296 0     0 1   my $self = shift;
297 0           my $attr = 'episode';
298 0           $self->__get_obj_attr($attr);
299             }
300              
301             =head2 episode_to_int
302              
303             Return episode as an integer
304              
305             =cut
306              
307             sub episode_to_int {
308              
309 0     0 1   my $self = shift;
310 0 0         return int($self->episode()) if defined $self->{episode};
311 0           return undef;
312             }
313              
314             =head2 source
315              
316             Return the source of tv show. Return '' if not defined.
317             Yet to be coded.
318              
319             =cut
320              
321              
322             =head2 is_multi_episode
323              
324             Return 1 if this is a multi-episode file SXXEXXEXX. Return 0 if false
325              
326             This is true if {endep} is defined.
327              
328             =cut
329              
330             sub is_multi_episode {
331              
332 0     0 1   my $self = shift;
333              
334 0 0         return 1 if defined $self->{endep};
335 0           return 0;
336              
337             }
338              
339             =head2 season_episode
340              
341             Return SXXEXX or SXXEXXEXX for single or multi episode files. Return '' if not
342             created
343              
344             This would only return an empty string if the show_name is not formated as
345             show_name.SXX.*
346              
347             =cut
348              
349             sub season_episode {
350              
351 0     0 1   my $self = shift;
352 0           my $s_e = '';
353              
354             # endep indicates that this is is_multi_episode file. SXXEXXEXX
355 0 0 0       if ((defined $self->{episode}) && (!defined $self->{endep})) {
    0 0        
356 0           $s_e = sprintf("S%02dE%02d", $self->{season}, $self->{episode});
357             } elsif ((defined $self->{episode}) && (defined $self->{endep})) {
358             # This is a multi-Episde
359             $s_e = sprintf("S%02dE%02dE%02d", $self->{season}, $self->{episode},
360 0           $self->{endep});
361             };
362 0           return $s_e;
363              
364             }
365              
366             =head2 has_year
367              
368             Return 1 if year is defined else return 0
369              
370             =cut
371              
372             sub has_year {
373              
374 0     0 1   my $self = shift;
375              
376 0 0         return 1 if defined $self->{year};
377 0           return 0;
378              
379             }
380              
381             =head2 year
382              
383             Return the year found in the file name. Return '' if {year} is not defined.
384              
385             =cut
386              
387             sub year {
388              
389 0     0 1   my $self = shift;
390 0           my $attr = 'year';
391 0           $self->__get_obj_attr($attr);
392             }
393              
394             =head2 month
395              
396             Return the month found in the file name. Return '' if {month} is not defined.
397              
398             =cut
399              
400             sub month {
401              
402 0     0 1   my $self = shift;
403 0           my $attr = 'month';
404 0           $self->__get_obj_attr($attr);
405             }
406              
407             =head2 date
408              
409             Return the date found in the file name. Return '' if {date} is not defined.
410              
411             =cut
412              
413             sub date {
414              
415 0     0 1   my $self = shift;
416 0           my $attr = 'date';
417 0           $self->__get_obj_attr($attr);
418             }
419              
420             =head2 ymd
421              
422             Return the complete date string as 'YYYY.MM.DD' Ruturn '' if attributes
423             {year}, {month}, and {date} are not defined.
424              
425             =cut
426              
427             sub ymd {
428              
429 0     0 1   my $self = shift;
430              
431             return $self->{year} . "." . $self->{month} . "." . $self->{date}
432 0 0 0       if defined $self->{year} && defined $self->{month};
433 0           return '';
434             }
435              
436             =head2 resolution
437              
438             Return resolution found in the file name. Return '' if {resolution} is not defined.
439              
440             =cut
441              
442             sub resolution {
443              
444 0     0 1   my $self = shift;
445 0           my $attr = 'resolution';
446 0           $self->__get_obj_attr($attr);
447             }
448              
449             #=head2 network
450              
451             #Return network if found '' if not defined.
452              
453             #Networks: AMZN, HULU, ABC and so on.
454              
455             #=cut
456              
457             sub _network {
458              
459 0     0     my $self = shift;
460 0           my $attr = 'network';
461 0           $self->__get_obj_attr($attr);
462              
463              
464             }
465              
466             =head2 release_group
467              
468             Return release_group found in the file name. Return '' if {release_group} is not defined.
469              
470             =cut
471              
472             sub release_group {
473              
474 0     0 1   my $self = shift;
475 0           my $attr = 'release_group';
476 0           $self->__get_obj_attr($attr);
477             }
478              
479             =head2 episode_name
480              
481             Return episode_name. Return '' if {extra_meta} is not defined or can not
482             determine episode name.
483              
484             Note: episode name MUST directly follow SXXEXX or it can not be found.
485              
486             =cut
487              
488             sub episode_name {
489              
490 0     0 1   my $self = shift;
491 0           my $attr = 'episode_name';
492 0           $self->__get_obj_attr($attr);
493             }
494              
495             =head2 strip_episode_name
496              
497             Return episode name without delimiters.
498              
499             =cut
500              
501             sub strip_episode_name {
502              
503 0     0 1   my $self = shift;
504              
505 0 0         return if !$self->is_tv_show();
506              
507 0           (my $newString = $self->{episode_name}) =~ s/[\._-]/ /g;
508 0           return $newString;
509              
510             }
511              
512             =head2 country
513              
514             Return country found in {show_name}. Return '' if not defined
515              
516             =cut
517              
518             sub country {
519              
520 0     0 1   my $self = shift;
521 0           my $attr = 'country';
522 0           $self->__get_obj_attr($attr);
523             }
524              
525             =head2 ext
526              
527             Return file extension. {ext}
528              
529             =cut
530              
531             sub ext {
532              
533 0     0 1   my $self = shift;
534              
535 0 0         return $self->{ext} if defined $self->{ext};
536             # Return '' or undef? this sould never even happen.
537 0           return undef;
538              
539             }
540              
541             =head2 is_tv_show
542              
543             Return 1 if identified as a TV Show. Default is 0
544              
545             =cut
546              
547             sub is_tv_show {
548              
549 0     0 1   my ($self) = @_;
550              
551 0 0 0       if (defined $self->{season} && defined $self->{episode}) {
    0 0        
      0        
552 0           return 1;
553             } elsif (defined $self->{year} && $self->{month} && $self->{date}) {
554 0           return 1;
555             }
556             # This is not a TVshow
557 0           return 0;
558             }
559              
560             =head2 is_tv_subtitle
561              
562             Return 1 if the file is a subtitle file, 0 if {is_subtitle} is not defined.
563              
564             The file must also return true for is_tv_show() or the result is 0
565              
566             =cut
567              
568             sub is_tv_subtitle {
569              
570 0     0 1   my $self = shift;
571              
572 0 0 0       return 1 if (($self->is_tv_show()) && (defined $self->{is_subtitle}));
573 0           return 0;
574             }
575              
576             =head2 has_subtitle_lang
577              
578             Return 1 if subtitle language was found, Return 0 if {subtitle_lang} is not defined.
579              
580             Must also return 1 for is_tv_subtitle()
581              
582             =cut
583              
584             sub has_subtitle_lang {
585              
586 0     0 1   my $self = shift;
587              
588 0 0 0       return 1 if (($self->is_tv_subtitle()) && (defined $self->{subtitle_lang}));
589 0           return 0;
590             }
591              
592             =head2 subtitle_lang
593              
594             Return the language of the subtitle file: eng or en. Return '' if {subtitle_lang} is not defined.
595              
596             =cut
597              
598             sub subtitle_lang {
599              
600 0     0 1   my $self = shift;
601 0           my $attr = 'subtitle_lang';
602 0           $self->__get_obj_attr($attr);
603             }
604              
605             =head2 has_country
606              
607             Return 1 if country was found, Return 0 if {country} is not defined.
608              
609             Must also return 1 for is_tv_subtitle()
610              
611             =cut
612              
613             sub has_country {
614              
615 0     0 1   my $self = shift;
616              
617 0 0 0       return 1 if (($self->is_tv_show()) && (defined $self->{country}));
618 0           return 0;
619             }
620              
621             =head2 is_by_date
622              
623             Return 1 if by date. Default is 0
624              
625             This will be true where year, month and date are all defined. show_name.yyyy.mm.dd.ext
626              
627             =cut
628              
629             sub is_by_date {
630              
631 0     0 1   my $self = shift;
632              
633 0 0 0       if (defined $self->{year} && defined $self->{month} &&
      0        
634             defined $self->{date}) {
635 0           return 1;
636             }
637 0           return 0;
638             }
639              
640             =head2 is_by_season
641              
642             Return 1 if by season. Default is 0
643              
644             Requires {season} and {episode} to be defined.
645              
646             =cut
647              
648             sub is_by_season {
649              
650 0     0 1   my $self = shift;
651 0 0 0       if (defined $self->{season} && defined $self->{episode}) {
652 0           return 1;
653             }
654 0           return 0;
655             }
656              
657             sub _set_tvshow_organize_name {
658              
659 0     0     my $self = shift;
660              
661             # This is not a tv show file. Exit method now.
662 0 0         return if !$self->is_tv_show();
663              
664 0 0         $self->{organize_name} = $self->{show_name} if defined $self->{show_name};
665             }
666              
667             sub _isolate_name_year {
668              
669 0     0     my $self = shift;
670              
671             # This is not a tv show file. Exit method now.
672 0 0         return if !$self->is_tv_show();
673              
674 0           my @exceptions = qw(The.4400);
675              
676 0           my $regex;
677 0 0         if ($] >= 5.010000) { # Perl 5.10 > has regex group support
678 0           $regex = '(?.*[^\s(_.])[\s(_.]+(?\d{4})';
679             } else { # Perl versions below 5.10 do not have group support
680 0           $regex = '(.*[^\s(_.])[\s(_.]+(\d{4})';
681             }
682             # Skip isolation if {show_name} is in the array @exceptions
683             # We do not want to modify the file name.
684 0           foreach (@exceptions) {
685 0 0         if ($self->{show_name} =~ m/$_/) {
686 0           $self->{do_not_strip} = 1;
687 0           return;
688             }
689             }
690              
691             # break {show_name} from year
692 0 0         if ($self->{show_name} =~ /$regex/gi) {
693             # First copy {show_name} to new attr
694 0           $self->{original_show_name} = $self->{show_name};
695             # Support to handle either case of group or no groups in regex
696 0   0       $self->{year} = $+{year} || $2; #$2 equals group year
697 0   0       $self->{show_name} = $+{show_name} || $1; # $1 equals group show_name
698             }
699             }
700              
701             # TODO: Code _get_source (HTDV, AMZ ?)
702              
703             sub _get_episode_name {
704              
705 0     0     my $self = shift;
706              
707             # This is not a tv show file. Exit method now.
708 0 0 0       return if !$self->is_tv_show() || !defined $self->{extra_meta};
709              
710             # Dont bother search as there is no Episode Name extra_meta starts
711             # with 720p or AMZN or WEB
712 0 0         return if $self->{extra_meta} =~ /^([0-9]{3,4}(p|i)|AMZN|WEB)/i;
713              
714             # Loop through possible regex list to find suiable regex to use
715 0           for my $pat (@episode_name_patterns) {
716 0 0         if ($self->{extra_meta} =~ /$pat->{re}/i) {
717             # We have a match we will exit after this loop
718             # Use this {re} as our regex
719 0           $self->{episode_name_regex} = $pat->{re};
720             # We have a match so we are skipping all other @filePatterns
721 0           last;
722             }
723             }
724             # Only do the extraction of we found a matching regex to use
725 0 0         if (defined $self->{episode_name_regex}) {
726 0 0         if ($self->{extra_meta} =~ /$self->{episode_name_regex}/i) {
727 0           $self->{episode_name} = $+{episode_name};
728             }
729             } else {
730             # This is only being set for use in testing.
731             # There might be an Episode name, but no regex match found
732 0           $self->{no_episode_name_regex} = 1;
733             }
734             }
735              
736             sub _get_release_group {
737              
738 0     0     my $self = shift;
739              
740             # This is not a tv show file. Exit method now.
741 0 0 0       return if !$self->is_tv_show() || !defined $self->{extra_meta};
742              
743 0           my $regex;
744 0 0         if ($] >= 5.010000) { # Perl 5.10 > has regex group support
745 0           $regex = '[\[]?(?Pfov|vtv|ettv|rmteam|eztv)[]]?';
746             } else { # Perl versions below 5.10 do not have group support
747 0           $regex = '[\[]?(fov|vtv|ettv|rmteam|eztv)[]]?';
748             }
749 0 0         if ($self->{extra_meta} =~ /$regex/gi) {
750 0   0       $self->{release_group} = $+{release_group} || $1; # $1 equals group release_group
751             }
752             }
753              
754             sub _get_network {
755              
756 0     0     my $self = shift;
757              
758 0 0 0       return if !$self->is_tv_show() || !defined $self->{extra_meta};
759              
760             #Build REGEX from array of Networks
761 0           my $regex = '(?P';
762 0           $regex .= join('|', @networks);
763 0           $regex .= ')';
764             #my $regex = '(?PABC|AMZN|BBC|CBS|CC|CW|DCU|DSNY|FBWatch|FREE|FOX|HULU|iP|LIFE|MTV|NBC|NICK|FC|RED|TF1|STZ)';
765 0 0         if ($self->{extra_meta} =~ /$regex/gi) {
766 0           $self->{network} = $+{network};
767             }
768             }
769              
770             sub _get_resolution {
771              
772 0     0     my $self = shift;
773              
774             # This is not a tv show file. Exit method now.
775 0 0 0       return if !$self->is_tv_show() || !defined $self->{extra_meta};
776              
777 0           my $regex;
778 0 0         if ($] >= 5.010000) { # Perl 5.10 > has regex group support
779 0           $regex = '(?P[0-9]{3,4}[p|i])';
780             } else { # Perl versions below 5.10 do not have group support
781 0           $regex = '([0-9]{3,4}[p|i])';
782             }
783 0 0         if ($self->{extra_meta} =~ /$regex/gi) {
784 0   0       $self->{resolution} = $+{resolution} || $1; # $1 equals group resolution
785             }
786              
787             }
788              
789             sub _get_country {
790              
791 0     0     my $self = shift;
792              
793             # This is not a tv show file. Exit method now.
794 0 0         return if !$self->is_tv_show();
795              
796 0           my $regex;
797 0 0         if ($] >= 5.010000) { # Perl 5.10 > has regex group support
798 0           $regex = '[(]?(?P\w{2})[)]?$';
799             } else { # Perl versions below 5.10 do not have group support
800 0           $regex = '[(]?(\w{2})[)]?$';
801             }
802 0 0         if ($self->{show_name} =~ /$regex/g) {
803             # Check if string at the end of {show_name} is in the array of accepted
804             # country strings. If not, we do not set {country}
805 0 0         if (grep { $_ eq $1 } @{$self->{valid_countries}}) {
  0            
  0            
806 0   0       $self->{country} = $+{country} || $1; # $1 equals group country
807 0           $self->{show_name} =~ s/\(?$1\)?//;
808 0           chop($self->{show_name});
809             }
810             }
811             }
812              
813             sub _is_tv_subtitle {
814              
815 0     0     my $self = shift;
816              
817             # This is not a tv show file. Exit method now.
818 0 0         return if !$self->is_tv_show();
819              
820 0           my @list_of_subtitle_ext = qw(srt smi ssa ass vtt);
821              
822             # Check if {ext} is a subtitle extension {is_subtitle} set to 1 if true.
823 0 0         if (grep { $_ eq $self->{ext}} @list_of_subtitle_ext) {
  0            
824 0           $self->{is_subtitle} = 1;
825             }
826             }
827              
828             sub _get_subtitle_lang {
829              
830 0     0     my $self = shift;
831              
832             # This is not a subtitle file. Exit method now.
833 0 0         return if !defined $self->{is_subtitle};
834              
835 0           my $regex;
836 0 0         if ($] >= 5.010000) { # Perl 5.10 > has regex group support
837 0           $regex = '(?P[a-z]{2,})$';
838             } else { # Perl versions below 5.10 do not have group support
839 0           $regex = '([a-z]{2,})$';
840             }
841 0 0         if ($self->{extra_meta} =~ /$regex/gi) {
842 0   0       $self->{subtitle_lang} = $+{lang} || $1; # $1 equals group lang
843             }
844             }
845              
846             sub __get_obj_attr {
847              
848 0     0     my ($self, $attr) = @_;
849              
850 0 0         return $self->{$attr} if defined $self->{$attr};
851 0           return '';
852              
853             }
854              
855             =head1 AUTHOR
856              
857             Adam Spann, C<< >>
858              
859             =head1 BUGS
860              
861             Please report any bugs or feature requests to C, or through
862             the web interface at L. I will be notified, and then you'll
863             automatically be notified of progress on your bug as I make changes.
864              
865              
866              
867              
868             =head1 SUPPORT
869              
870             You can find documentation for this module with the perldoc command.
871              
872             perldoc File::TVShow::Info
873              
874              
875             You can also look for information at:
876              
877             =over 4
878              
879             =item * RT: CPAN's request tracker (report bugs here)
880              
881             L
882              
883             =item * AnnoCPAN: Annotated CPAN documentation
884              
885             L
886              
887             =item * CPAN Ratings
888              
889             L
890              
891             =item * Search CPAN
892              
893             L
894              
895             =back
896              
897              
898             =head1 ACKNOWLEDGEMENTS
899              
900              
901             =head1 LICENSE AND COPYRIGHT
902              
903             Copyright 2019 Adam Spann.
904              
905             This program is free software; you can redistribute it and/or modify it
906             under the terms of either: the GNU General Public License as published
907             by the Free Software Foundation; or the Artistic License.
908              
909             See L for more information.
910              
911              
912             =cut
913              
914             1; # End of File::TVShow::Info