File Coverage

blib/lib/URI/Parse/Instagram.pm
Criterion Covered Total %
statement 11 25 44.0
branch 0 8 0.0
condition 0 2 0.0
subroutine 4 6 66.6
pod 1 1 100.0
total 16 42 38.1


line stmt bran cond sub pod time code
1             package URI::Parse::Instagram;
2              
3 1     1   340933 use 5.010001;
  1         5  
4 1     1   32 use strict;
  1         3  
  1         36  
5 1     1   6 use warnings;
  1         3  
  1         128  
6              
7             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
8             our $DATE = '2025-03-27'; # DATE
9             our $DIST = 'URI-Parse-Instagram'; # DIST
10             our $VERSION = '0.001'; # VERSION
11              
12 1     1   7 use Exporter qw(import);
  1         3  
  1         2234  
13             our @EXPORT_OK = qw(parse_instagram_url);
14              
15             our %SPEC;
16              
17             our $re_proto_http = qr!(?:https?://)!i;
18             our $re_user = qr/(?:[A-Za-z0-9_]+|[A-Za-z0-9_](?:\.?[A-Za-z0-9])+[A-Za-z0-9_])/;
19             our $re_user_strict = qr/(?:[A-Za-z0-9_]{1,30}|[A-Za-z0-9_](?:[A-Za-z0-9_]|\.(?!\.)){1,28}[A-Za-z0-9_])/;
20             our $re_end_or_q = qr/(?:[?&#]|\z)/;
21              
22             $SPEC{parse_instagram_url} = {
23             v => 1.1,
24             summary => 'Parse information from an instagram URL',
25             description => <<'MARKDOWN',
26              
27             Return a hash of information from an Instagram URL, or undef if URL cannot be
28             parsed. Can potentially return `_errors` or `_warnings` keys, each being an
29             array of error/warning messages.
30              
31             MARKDOWN
32             args => {
33             url => {
34             schema => 'str*',
35             req => 1,
36             pos => 0,
37             },
38             },
39             args_as => 'array',
40             result => {
41             schema => 'hash',
42             },
43             result_naked => 1,
44             examples => [
45             {
46             name => "insta/USER #1",
47             args => {url=>'https://www.instagram.com/foo'},
48             result => {user=>'foo'},
49             },
50             {
51             name => "insta/USER #2",
52             args => {url=>'https://www.instagram.com/foo.bar/'},
53             result => {user=>'foo.bar'},
54             },
55             {
56             name => "insta/USER #3",
57             args => {url=>'https://www.instagram.com/foo_bar?igsh=blah&utm_source=qr'},
58             result => {user=>'foo_bar'},
59             },
60              
61             {
62             name => 'unknown',
63             args => {url=>'https://www.google.com/'},
64             result => undef,
65             },
66             ],
67             };
68             sub parse_instagram_url {
69 0     0 1   my $url = shift;
70              
71 0           my $res;
72             my $code_add_error = sub {
73 0   0 0     $res->{_errors} //= [];
74 0           push @{ $res->{_errors} }, $_[0];
  0            
75 0           };
76              
77             # metacpan
78 0 0         if ($url =~ s!\A$re_proto_http?(?:www\.)?instagram\.com/?!!i) {
79              
80             #$res->{site} = 'insta';
81              
82 0 0         if ($url =~ m!\A($re_user)/*$re_end_or_q!i) {
83 0           $res->{user} = lc $1;
84 0 0         $code_add_error->("Username too long") if length($res->{user}) > 30;
85 0 0         $code_add_error->("Invalid username") unless $res->{user} =~ m!\A$re_user_strict\z!;
86             } else {
87 0           $code_add_error->("Cannot find username");
88             }
89             } else {
90 0           return undef; ## no critic: Subroutines::ProhibitExplicitReturnUndef
91             }
92              
93 0           $res;
94             }
95              
96             1;
97             # ABSTRACT: Parse information from an instagram URL
98              
99             __END__