root/branches/hackathon-summary/plagger/lib/Plagger/Plugin.pm

Revision 1622 (checked in by miyagawa, 2 years ago)

merge from trunk

  • Property svn:keywords set to Id Revision
Line 
1 package Plagger::Plugin;
2 use strict;
3 use base qw( Class::Accessor::Fast );
4
5 __PACKAGE__->mk_accessors( qw(conf rule rule_hook cache) );
6
7 use Plagger::Cookies;
8 use Plagger::Crypt;
9 use Plagger::Rule;
10 use Plagger::Rules;
11
12 use FindBin;
13 use File::Find::Rule ();
14 use File::Spec;
15 use Scalar::Util qw(blessed);
16
17 sub new {
18     my($class, $opt) = @_;
19     my $self = bless {
20         conf => $opt->{config} || {},
21         rule => $opt->{rule},
22         rule_op => $opt->{rule_op} || 'AND',
23         rule_hook => '',
24         meta => {},
25     }, $class;
26     $self->init();
27     $self;
28 }
29
30 sub init {
31     my $self = shift;
32
33     if (my $rule = $self->{rule}) {
34         $rule = [ $rule ] if ref($rule) eq 'HASH';
35         my $op = $self->{rule_op};
36         $self->{rule} = Plagger::Rules->new($op, @$rule);
37     } else {
38         $self->{rule} = Plagger::Rule->new({ module => 'Always' });
39     }
40
41     $self->walk_config_encryption();
42 }
43
44 sub walk_config_encryption {
45     my $self = shift;
46     my $conf = $self->conf;
47
48     $self->do_walk($conf);
49 }
50
51 sub do_walk {
52     my($self, $data) = @_;
53     return unless defined($data) && ref $data;
54
55     if (ref($data) eq 'HASH') {
56         for my $key (keys %$data) {
57             if ($key =~ /password/) {
58                 $self->decrypt_config($data, $key);
59             }
60             $self->do_walk($data->{$key});
61         }
62     } elsif (ref($data) eq 'ARRAY') {
63         for my $value (@$data) {
64             $self->do_walk($value);
65         }
66     }
67 }
68
69 sub decrypt_config {
70     my($self, $data, $key) = @_;
71
72     my $decrypted = Plagger::Crypt->decrypt($data->{$key});
73     if ($decrypted eq $data->{$key}) {
74         Plagger->context->add_rewrite_task($key, $decrypted, Plagger::Crypt->encrypt($decrypted, 'base64'));
75     } else {
76         $data->{$key} = $decrypted;
77     }
78 }
79
80 sub conf { $_[0]->{conf} }
81 sub rule { $_[0]->{rule} }
82
83 sub dispatch_rule_on {
84     my($self, $hook) = @_;
85     $self->rule_hook && $self->rule_hook eq $hook;
86 }
87
88 sub class_id {
89     my $self = shift;
90
91     my $pkg = ref($self) || $self;
92        $pkg =~ s/Plagger::Plugin:://;
93     my @pkg = split /::/, $pkg;
94
95     return join '-', @pkg;
96 }
97
98 # subclasses may overload to avoid cache sharing
99 sub plugin_id {
100     my $self = shift;
101     $self->class_id;
102 }
103
104 sub assets_dir {
105     my $self = shift;
106     my $context = Plagger->context;
107
108     if ($self->conf->{assets_path}) {
109         return $self->conf->{assets_path}; # look at config:assets_path first
110     }
111
112     my $assets_base =
113         $context->conf->{assets_path} ||              # or global:assets_path
114         File::Spec->catfile($FindBin::Bin, "assets"); # or "assets" under plagger script
115
116     return File::Spec->catfile(
117         $assets_base, "plugins", $self->class_id,
118     );
119 }
120
121 sub log {
122     my $self = shift;
123     Plagger->context->log(@_, caller => ref($self));
124 }
125
126 sub cookie_jar {
127     my $self = shift;
128
129     my $agent_conf = Plagger->context->conf->{user_agent} || {};
130     if ($agent_conf->{cookies}) {
131         return Plagger::Cookies->create($agent_conf->{cookies});
132     }
133
134     return $self->cache->cookie_jar;
135 }
136
137 sub templatize {
138     my($self, $file, $vars) = @_;
139
140     my $context = Plagger->context;
141     $vars->{context} ||= $context;
142
143     my $template = Plagger::Template->new($context, $self);
144     $template->process($file, $vars, \my $out) or $context->error($template->error);
145
146     $out;
147 }
148
149 sub load_assets {
150     my($self, $rule, $callback) = @_;
151
152     unless (blessed($rule) && $rule->isa('File::Find::Rule')) {
153         $rule = File::Find::Rule->name($rule);
154     }
155
156     # $rule isa File::Find::Rule
157     for my $file ($rule->in($self->assets_dir)) {
158         my $base = File::Basename::basename($file);
159         $callback->($file, $base);
160     }
161 }
162
163 1;
Note: See TracBrowser for help on using the browser.