Skip to content

Instantly share code, notes, and snippets.

@tyru
Created May 3, 2009 23:32
Show Gist options
  • Select an option

  • Save tyru/106200 to your computer and use it in GitHub Desktop.

Select an option

Save tyru/106200 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
# vim:ft=perl:
use strict;
use warnings;
use utf8;
use DateTime;
use File::Basename qw(basename);
use File::Copy qw(copy);
use FileHandle;
use Getopt::Long;
use LWP::Simple qw(get);
use List::Util qw(first);
use Path::Class ();
use Perl6::Say;
use Pod::Usage;
use URI;
use Web::Scraper;
# 引数指定めんどいならこれを直接変えてもいい
my $debug = 0;
my $backup = 0;
my $all = 0;
my $only_check = 0;
my $trunk = 0;
my $vimp_plugin_dir = Path::Class::dir($ENV{HOME}, 'vimperator', 'plugin');
my $trunk_uri = 'http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk';
my $branch_uri = 'http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/branches/1.2';
# 引数
my ($coderepos_uri, $needhelp);
GetOptions(
all => \$all,
backup => \$backup,
check => \$only_check,
debug => \$debug,
help => \$needhelp,
trunk => \$trunk,
) or pod2usage(-verbose => 2, -exitval => 0);
pod2usage(-verbose => 2, -exitval => 0) if($needhelp);
if ($trunk) {
$coderepos_uri = URI->new($trunk_uri);
} else {
$coderepos_uri = URI->new($branch_uri);
}
STDOUT->autoflush(1);
STDERR->autoflush(1);
print "connecting [$coderepos_uri]...";
# プラグインの名前と更新日時をスクレイプ
my $res = scraper {
process 'td.name>a.file',
'files[]' => {
'name' => 'TEXT',
'href' => '@href'
};
process 'td.name>a.dir',
'dirs[]' => 'TEXT';
process 'td.age>a.timeline',
'updated_times[]' => '@href';
}->scrape($coderepos_uri);
print "Done.\n\n";
for (1..@{$res->{dirs}}) {
shift @{$res->{updated_times}}
}
my %plugin = map {
$_->{name}, { href => $_->{href}, updated_time => shift @{$res->{updated_times}} }
} @{$res->{files}};
# キャッシュとか
# my $locale = DateTime::TimeZone->new(name => 'local');
my $locale = DateTime::TimeZone->new(name => 'JST-9');
my $plugin_dir = $vimp_plugin_dir->file('*.js');
my @script_names = keys %plugin;
my (%updates, @err);
foreach my $script_path (glob $plugin_dir) {
my $script = basename $script_path;
my $matched = first { defined $_ && $script eq $_ } @script_names;
if (not $matched) { # プラグインがCodereposに見つからなかった
push @err, $script;
next;
}
$script = $matched;
# コミットされた時間を切り抜き
my $ret = $plugin{$script}{updated_time} =~
m#\?from=(\d+)-(\d+)-(\d+)T(\d{2})#;
my ($year, $month, $day, $hour) = ($1, $2, $3, $4);
# それぞれのオブジェクトを作成
my $commited_day = DateTime->new(year => $year, month => $month,
day => $day, hour => $hour,
time_zone => $locale);
my $downloaded_day = DateTime->from_epoch(epoch => (stat $script_path)[9]);
# 経過時間を計算
my $passed = $downloaded_day - $commited_day;
# 新しいのがあった
if($all || $passed->is_negative) {
say "$script will be updated...";
$updates{$script_path} = $plugin{$script}{href};
}
}
print "\n";
# チェックのみ
if ($only_check) {
if (%updates) {
say "The newer version is available.";
foreach my $fn (keys %updates) {
say " " . basename $fn;
}
} else {
say "There were no updates.";
}
exit;
}
if (%updates) {
my @success;
foreach my $fn (keys %updates) {
my $base_fn = basename $fn;
# $fnにはスクリプトへのフルパスが入る
say "updating $base_fn...";
sleep 2; # 待つ
my $res = scraper {
process 'div#altlinks>ul>li.last>a', 'download' => '@href';
}->scrape($updates{$fn});
if ($backup) {
my $macro_dir = $vimp_plugin_dir->parent->subdir('macros')->absolute;
mkdir $macro_dir unless -d $macro_dir;
my $old_file = $vimp_plugin_dir->file($base_fn)->absolute;
# File::Copy::copy は$!にsetするらしい
copy($vimp_plugin_dir->file($base_fn),
$macro_dir->file($base_fn)) or warn $!;
}
my $FH = FileHandle->new("> $fn");
unless (defined $FH) {
warn "error: Couldn't open $fn...\n";
next;
}
binmode($FH);
$FH->print(get($res->{download}));
$FH->close;
# 成功
push @success, $base_fn;
}
printf "\n\nupdated %d files:\n", scalar @success;
foreach my $script (@success) {
# this is not(ry
say " $script";
}
} else {
say "There were no updates.";
}
if (@err) {
warn "\n\nNot found in coderepos:\n";
warn " $_\n" for @err;
}
__END__
=head1 NAME
check_vimpe_update.pl - auto update vimperator plugins from coderepos
=head1 SYNOPSIS
$ perl check_vimpe_update.pl [-abht]
=head1 OPTIONS
a, all update all vimperator plugins even if not outdated.
b, backup backup your script in $HOME/Vimperator/macro directory.
c, check only check. show available version if newer version is available.
h, help this help text.
t, trunk download from trunk version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment