91 lines
2 KiB
Perl
91 lines
2 KiB
Perl
#!perl
|
|
use RevBank::Products qw(read_products);
|
|
use FindBin qw($Bin);
|
|
|
|
my $fn = ".revbank.oepl";
|
|
my $hex = '[0-9A-F]';
|
|
my $mac_regex = qr/^(?:$hex {12}|$hex {14}|$hex {16})$/x;
|
|
|
|
sub _create() {
|
|
open my $fh, '>>', $fn;
|
|
}
|
|
|
|
sub _run(@args) {
|
|
local $ENV{REVBANK_SKIP_LOCK} = 1;
|
|
system perl => "$Bin/contrib/openepaperlink.pl", @args;
|
|
}
|
|
|
|
sub _read_oepl() {
|
|
return { map { (split " ")[0, 1] } slurp $fn };
|
|
}
|
|
|
|
sub _touch() {
|
|
utime undef, undef, $fn;
|
|
}
|
|
|
|
sub command :Tab(openepaperlink) ($self, $cart, $command, @) {
|
|
if ($command =~ $mac_regex) {
|
|
my $mac2product = _read_oepl;
|
|
return REDO, $mac2product->{$command} if exists $mac2product->{$command};
|
|
}
|
|
|
|
$command eq 'openepaperlink' or return NEXT;
|
|
|
|
return "Product ID (or 'unlink')", sub ($self, $cart, $product_id, @) {
|
|
my $product;
|
|
|
|
if ($product_id ne 'unlink') {
|
|
$product = read_products->{$product_id} or return REJECT, "No such product.";
|
|
$product_id = $product->{id}; # don't use alias
|
|
}
|
|
|
|
return "Tag MAC", sub ($self, $cart, $mac, @) {
|
|
$mac =~ $mac_regex or return REJECT, "Malformed MAC.";
|
|
|
|
_run erase => $mac if $product_id eq 'unlink'; # while it's still in the .oepl
|
|
|
|
_create;
|
|
my $found = 0;
|
|
rewrite $fn, sub($line) {
|
|
my ($m) = split " ", $line;
|
|
return $line if $m ne $mac;
|
|
$found++;
|
|
return undef if $product_id eq 'unlink';
|
|
return "$mac $product_id\n" if $m eq $mac;
|
|
};
|
|
if (!$found and $product_id ne 'unlink') {
|
|
append $fn, "$mac $product_id\n";
|
|
}
|
|
_run $mac unless $product_id eq 'unlink';
|
|
|
|
return ACCEPT;
|
|
};
|
|
};
|
|
}
|
|
|
|
sub hook_products_changed($class, $changes, $mtime, @) {
|
|
-f $fn or return;
|
|
|
|
return with_lock {
|
|
$mtime >= (stat $fn)[9] or return;
|
|
|
|
my @macs;
|
|
my %deleted;
|
|
my %product2mac = reverse %{ _read_oepl() };
|
|
|
|
for my $pair (@$changes) {
|
|
my ($old, $new) = @$pair;
|
|
|
|
my $id = defined($new) ? $new->{id} : $old->{id};
|
|
$product2mac{$id} or next;
|
|
|
|
push @macs, $product2mac{$id};
|
|
}
|
|
|
|
@macs or return;
|
|
_run @macs;
|
|
|
|
sleep 1 if $mtime == time;
|
|
_touch;
|
|
};
|
|
}
|