root/veekun/trunk/lib/Vee/Utils.pm

Revision 474, 4.5 KB (checked in by eevee, 8 months ago)

Fixed a handful of warnings.

Line 
1package Vee::Utils;
2
3use Socket qw//;
4use List::Util qw/first/;
5use Digest::SHA1 qw/sha1_hex/;
6
7=head1 NAME
8
9Vee::Utils - Assorted utility functions
10
11=head1 SYNOPSIS
12
13Coming soon
14
15=head1 DESCRIPTION
16
17Just a collection of small C<sub>s I've written that tend to be more useful
18than I expected.
19
20=head1 FUNCTIONS
21
22Coming soon
23
24=cut
25
26sub hsv2rgb {
27    my ($h, $s, $v) = @_;
28    $h /= 360; $s /= 256; $v /= 256;
29
30    if ($s <= 0.0) { return tohex(int $v * 256) x 3 }
31    else {
32        if ($h >= 1.0) { $h = 0.0 }
33        $h *= 6;
34        my $f = $h - int $h;
35        my $p = int(256 * $v * (1.0 - $s));
36        my $q = int(256 * $v * (1.0 - ($s * $f)));
37        my $t = int(256 * $v * (1.0 - ($s * (1.0 - $f))));
38        $v = int(256 * $v);
39        if (int $h == 0) { return hexcolor($v, $t, $p) }
40        elsif (int $h == 1) { return hexcolor($q, $v, $p) }
41        elsif (int $h == 2) { return hexcolor($p, $v, $t) }
42        elsif (int $h == 3) { return hexcolor($p, $q, $v) }
43        elsif (int $h == 4) { return hexcolor($t, $p, $v) }
44        elsif (int $h == 5) { return hexcolor($v, $p, $q) }
45    }
46}
47
48# get the postrank for a postcount
49# IN: user post count, OUT: post rank based on user post count
50
51sub postrank {
52    my ($post_count) = @_;
53    $post_count ||= 0;
54    for my $rank (
55        sort { $b <=> $a }
56        keys %{ Vee->config->{site}->{post_ranks} }
57    ) {
58        return Vee->config->{site}->{post_ranks}->{$rank} if $rank <= $post_count;
59    }
60    return "ERRORZ0RZ";
61}
62
63# get the percent width of the postbar for a given postcount
64# XXX: decide the best way to do this, preferably a smooth log curve
65sub post_width {
66    my ($post_count) = @_;
67    return $post_count / 1000;
68}
69
70# converts input to Linux-style newlines
71sub fix_newlines {
72    my $text = shift;
73    $text =~ s/\x0d\x0a?/\x0a/g;
74    $text =~ s/^\x0a+|\x0a+$//g;
75    return $text;
76}
77
78# remove all HTML
79sub cleanse {
80    my $text = shift;
81    return undef unless defined $text;
82    $text =~ s/&/&amp;/g;
83    $text =~ s/&amp;(#x?[0-9a-f]+;)/&$1/gi;
84    $text =~ s/</&lt;/g;
85    $text =~ s/>/&gt;/g;
86    $text =~ s/\"/&quot;/g;
87    $text =~ s:\x0D\x0A:<br/>:g;
88    $text =~ s:\x0D|\x0A:<br/>:g;
89    return $text;
90}
91
92# URL-validation regex
93# Inferred from the W3's BNF: http://www.w3.org/Addressing/URL/5_BNF.html
94# n.b.: Technically, the BNF says hostname parts (as delimited by dots)
95# should begin with a letter, but given that 'xalpha' includes dot this was
96# a bit clumsy to pull off in practice, so I left it lazy.
97my $url_xalphas = qr/[-_@.&+!*"'(),a-zA-Z0-9\$]/;
98our $IsValidURL = qr/ ^
99    (?: http | https | ftp ) :\/\/          # protocol
100    (?:
101        [a-zA-Z] $url_xalphas*              # hostname
102        | (?: \d{1,3} \. ){3} \d{1,3}       # IP
103    )
104    (?: : [0-9]+ )?                         # port
105    (?: \/                                  # path: leading slash
106        (?: $url_xalphas*                   # path: path part name
107          | %[a-fA-F][a-fA-F] )*            # path: escape
108    )*                                      # path: as many as you want
109    (?: \? $url_xalphas+ )?                 # query string
110    (?: \# $url_xalphas+ )?                 # anchor
111$ /x;
112
113
114sub pad { sprintf "%0$_[1]d", $_[0] }
115sub round { $_[1] ||= 0; return int($_[0] * 10 ** $_[1] + .5) / 10 ** $_[1]; }
116sub hexcolor { return tohex($_[0]).tohex($_[1]).tohex($_[2]); }
117sub tohex { return sprintf("%02x", $_[0]); }
118sub isnum { return (defined $_[0] and $_[0] =~ /^ [+-]? \d+ (?:\. [0-9]*)? $/x) }
119sub max { my ($i, $max); while (!defined $max) { $max = shift; } for $i (@_) { next unless defined $i; if ($i > $max) { $max = $i } } return $max; }
120sub min { my ($i, $min); while (!defined $min) { $min = shift; }  for $i (@_) { next unless defined $i; if ($i < $min) { $min = $i } } return $min; }
121sub sum { my $x; $x += $_ for (@_); return $x; }
122sub num { return (&isnum($_[0])) ? $_[0] : 0 }
123sub wordcap { my $text = $_[0]; $text =~ s#\b(.*?)\b#ucfirst $1#eg; return $text; }
124sub in { my $tmp = shift; for (@_) { return 1 if $tmp eq $_ } return 0 }
125sub urlencode { my $str = shift; $str =~ s/([^-_a-zA-Z0-9])/'%' . tohex(ord $1)/ge; return $str; }
126sub array { ref $_[0] ? @{ $_[0] } : ( $_[0] ) }
127
128sub inet_ntoa { Socket::inet_ntoa(pack 'N*', shift) }
129sub inet_aton { unpack 'N*', Socket::inet_aton(shift) }
130
131# name comes from what imageboards do, but really it's just a short hash
132sub tripcode { substr sha1_hex(shift), 0, 12 }
133
134=head1 AUTHOR
135
136Maintainer: Alex "Eevee" Munroe (C<veekun@veekun.com>)
137
138See the included F<AUTHORS> file for a full list of contributers.
139
140=head1 LICENSE
141
142See the included F<LICENSE> file.
143
144=cut
145
1461;
Note: See TracBrowser for help on using the browser.