diff --git a/Changes b/Changes index 01c175a4..648e1784 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,9 @@ 0.x + [ENHANCEMENTS] + + * Native copy of the Netdisco sort_port routine (#17) + [BUG FIXES] * Fix sidebar hiding not making main content reflow to full window width (#15) diff --git a/Netdisco/lib/Netdisco/Util.pm b/Netdisco/lib/Netdisco/Util.pm new file mode 100644 index 00000000..c830faeb --- /dev/null +++ b/Netdisco/lib/Netdisco/Util.pm @@ -0,0 +1,102 @@ +package Netdisco::Util; + +=head2 sort_port( $a, $b ) + +Sort port names with the following formatting types: + + A5 + 5 + FastEthernet0/1 + FastEthernet0/1-atm + 5.5 + Port:3 + +Interface is as Perl's own C - two input args and an integer return +value. + +Code taken from netdisco.pm. Thanks to Bradley Baetz (bbaetz) for improvements +in this sub. + +=cut + +sub sort_port { + my ($aval, $bval) = @_; + + my $numbers = qr{^(\d+)$}; + my $numeric = qr{^([\d\.]+)$}; + my $dotted_numeric = qr{^(\d+)\.(\d+)$}; + my $letter_number = qr{^([a-zA-Z]+)(\d+)$}; + my $wordcharword = qr{^([^:\/.]+)[\ :\/\.]+([^:\/.]+)(\d+)?$}; #port-channel45 + my $ciscofast = qr{^ + # Word Number slash (Gigabit0/) + (\D+)(\d+)[\/:] + # Groups of symbol float (/5.5/5.5/5.5), separated by slash or colon + ([\/:\.\d]+) + # Optional dash (-Bearer Channel) + (-.*)? + $}x; + + my @a = (); my @b = (); + + if ($aval =~ $dotted_numeric) { + @a = ($1,$2); + } elsif ($aval =~ $letter_number) { + @a = ($1,$2); + } elsif ($aval =~ $numbers) { + @a = ($1); + } elsif ($aval =~ $ciscofast) { + @a = ($1,$2); + push @a, split(/[:\/]/,$3), $4; + } elsif ($aval =~ $wordcharword) { + @a = ($1,$2,$3); + } else { + @a = ($aval); + } + + if ($bval =~ $dotted_numeric) { + @b = ($1,$2); + } elsif ($bval =~ $letter_number) { + @b = ($1,$2); + } elsif ($bval =~ $numbers) { + @b = ($1); + } elsif ($bval =~ $ciscofast) { + @b = ($1,$2); + push @b, split(/[:\/]/,$3),$4; + } elsif ($bval =~ $wordcharword) { + @b = ($1,$2,$3); + } else { + @b = ($bval); + } + + # Equal until proven otherwise + my $val = 0; + while (scalar(@a) or scalar(@b)){ + # carried around from the last find. + last if $val != 0; + + my $a1 = shift @a; + my $b1 = shift @b; + + # A has more components - loses + unless (defined $b1){ + $val = 1; + last; + } + + # A has less components - wins + unless (defined $a1) { + $val = -1; + last; + } + + if ($a1 =~ $numeric and $b1 =~ $numeric){ + $val = $a1 <=> $b1; + } elsif ($a1 ne $b1) { + $val = $a1 cmp $b1; + } + } + + return $val; +} + +1; diff --git a/Netdisco/lib/Netdisco/Web/Device.pm b/Netdisco/lib/Netdisco/Web/Device.pm index a2087fe0..f05a6385 100644 --- a/Netdisco/lib/Netdisco/Web/Device.pm +++ b/Netdisco/lib/Netdisco/Web/Device.pm @@ -5,7 +5,7 @@ use Dancer::Plugin::Ajax; use Dancer::Plugin::DBIC; use NetAddr::IP::Lite ':lower'; -use netdisco (); # for sort_port +use Netdisco::Util (); # for sort_port hook 'before' => sub { # list of port detail columns @@ -116,7 +116,7 @@ ajax '/ajax/content/device/ports' => sub { }) if param('c_connected'); # sort ports (empty set would be a 'no records' msg) - my $results = [ sort { &netdisco::sort_port($a->port, $b->port) } $set->all ]; + my $results = [ sort { &Netdisco::Util::sort_port($a->port, $b->port) } $set->all ]; return unless scalar @$results; content_type('text/html');