Skip to content

Instantly share code, notes, and snippets.

@phillipberndt
Created April 2, 2011 09:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phillipberndt/899352 to your computer and use it in GitHub Desktop.
Save phillipberndt/899352 to your computer and use it in GitHub Desktop.
Update Opera's urlfilter.ini from secure.fanboy.co.nz while preserving custom entries
#!/usr/bin/perl -w
use LWP::Simple;
use Storable;
use strict;
# Configuration
# You can define multiple urlfilter.ini lists to be downloaded
my @remotes = qw(
http://secure.fanboy.co.nz/adblock/opera/urlfilter.ini
);
# File in which to store a copy of the remote list
# This is required for the script to distinguish between removed
# entries and local entries
my $remote_store_filename = 'urlfilter.ini.plinfo';
##############################################################
if(`pgrep -clf opera` > 0) {
die "Opera is running. Not updating.";
}
# Download new urlfilter lists
my $remote_urlfilter_data;
for(@remotes) {
my $a_remote_urlfilter_data = get($_);
if($a_remote_urlfilter_data eq undef) {
warn "Failed to download urlfilter.ini from " . $_;
}
$a_remote_urlfilter_data =~ s/^.+\[exclude\]\s+//s;
$a_remote_urlfilter_data =~ s/^#.+\r?\n//m;
chomp $a_remote_urlfilter_data;
$remote_urlfilter_data .= $a_remote_urlfilter_data . "\n";
}
my %remote_urlfilter = map {
s/\s+$//;
if(m/^"([^"]+)"(=UUID:.+)?$/) {
lc $1 => $2 || 1;
}
elsif(m/^([^=]+)(=UUID:.+)?$/) {
lc $1 => $2 || 1;
}
} split(/\r?\n|\r(?!\n)/, $remote_urlfilter_data);
my %remote_urlfilter_old;
if($remote_store_filename) {
# Load stored copy of downloaded list
%remote_urlfilter_old = -e $remote_store_filename ? %{retrieve($remote_store_filename)} : {};
# And store a copy of the new list
store \%remote_urlfilter, $remote_store_filename;
}
# Load old urlfilter list
my $file_start = "";
open URLFILTER, "<urlfilter.ini";
while(1) {
my $line = <URLFILTER>;
$file_start .= $line;
last if($line =~ m/^\[exclude\]/);
last if eof;
}
unless($file_start) {
$file_start = <<EOF
Opera Preferences version 2.1
; Do not edit this file while Opera is running
; This file is stored in UTF-8 encoding
[prefs]
prioritize excludelist=1
[include]
*=UUID:1924F7C05D4311E0891A8B052607A998
EOF
}
if(eof) {
$file_start .= "[exclude]\n";
}
my %urlfilter = map {
s/\s+$//;
if(m/^"([^"]+)"(=UUID:.+)?$/) {
lc $1 => $2 || 1;
}
elsif(m/^([^=]+)(=UUID:.+)?$/) {
lc $1 => $2 || 1;
}
} <URLFILTER>;
close URLFILTER;
# Create an updated list
my ($local, $added, $removed);
$local = $added = $removed = 0;
# Remove remotely removed entries from local list
# This is only possible if the list was sync'ed before, since we can't tell
# local stuff apart from remotely removed..
for (keys %urlfilter) {
unless(exists($remote_urlfilter_old{$_})) {
# Must be present in old remote list, elsewise it's a local rule
$local++;
next;
}
next if(exists($remote_urlfilter{$_})); # But not present in new remote list
$removed++;
undef $urlfilter{$_};
}
# Insert new entries
for (keys %remote_urlfilter) {
next if(m/^\s*$/);
next if(exists($urlfilter{$_}));
$added++;
$urlfilter{$_} = 1;
}
# Write an updated list
if($added + $removed > 0) {
print "Update complete. " . $added . " entries added, " . $removed . " removed, " . $local . " local rules kept.\n";
open URLFILTER, ">urlfilter.ini";
print URLFILTER $file_start;
for (keys %urlfilter) {
next if m/^\s*$/;
next unless $urlfilter{$_};
if(m/=/) {
print URLFILTER '"' . $_ . '"';
}
else {
print URLFILTER $_;
}
print URLFILTER $urlfilter{$_} if($urlfilter{$_} ne 1);
print URLFILTER "\n";
}
close URLFILTER;
}
else {
print "urlfilter.ini is up to date\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment