Fix copyright notices
[videosite.git] / videosite-irssi.pl
1 # shim to connect libvideosite to irssi
2 #
3 # (c) 2007-2008 by Ralf Ertzinger <ralf@camperquake.de>
4 # licensed under GNU GPL v2
5 use strict;
6 use Irssi 20020324 qw (command_bind command_runsub signal_add_first signal_add_last);
7 use vars qw($VERSION %IRSSI);
8 use File::Spec;
9
10 #
11 # Initialize the config subsystem. Called by the core.
12 #
13 # Due to historic reasons this has to deal with a number of possible config sources:
14 # * irssi internal config
15 # * JSON config, old format
16 # * XML config, old format
17 #
18 # JSON and XML configs are parsed, converted and moved to the irssi internal
19 # format. This happens only once, as the config search stops with the first
20 # format found
21 #
22 sub config_init {
23     my $xmlconffile = File::Spec->catfile(Irssi::get_irssi_dir(), 'videosite.xml');
24     my $conffile = File::Spec->catfile(Irssi::get_irssi_dir(), 'videosite.json');
25     my $conf;
26
27     # Check for irssi internal config. If not found...
28     if (config_has(['config-version'])) {
29         # Configuration in irssi config file. We're done.
30         return;
31     }
32
33     # Try to find old config files and load them.
34     if (-r $conffile) {
35         eval {
36             local $/;
37             open(CONF, '<', $conffile);
38             $conf = JSON->new->utf8->decode(<CONF>);
39             close(CONF);
40         };
41     } elsif (-r $xmlconffile) {
42         $conf = XML::Simple::XMLin($xmlconffile, ForceArray => ['config', 'option', 'connectorlist'], KeepRoot => 1, KeyAttr => {'connector' => '+name', 'config' => 'module', 'option' => 'key'});
43     }
44
45     #
46     # Configuration conversion:
47     # Replace this structure:
48     #
49     # key => {
50     #   content => value
51     # }
52     #
53     # with this structure
54     #
55     # key => value
56     #
57     Irssi::print("Converting configuration, stage 1");
58
59     # Only the getter/grabbers have this, so just check that part of the config
60     foreach my $g (keys(%{$conf->{videosite}->{config}})) {
61         foreach (keys(%{$conf->{videosite}->{config}->{$g}->{option}})) {
62             if (exists($conf->{videosite}->{config}->{$g}->{option}->{$_}->{content})) {
63                 $conf->{videosite}->{config}->{$g}->{option}->{$_} = $conf->{videosite}->{config}->{$g}->{option}->{$_}->{content};
64             }
65         }
66     }
67
68     #
69     # Walk the configuration hash, creating irssi config entries for
70     # each leaf node.
71     #
72     # Some config values changed, so not the entire config is copied over.
73     # There is a helper function for this in libvideosite that we're using.
74     #
75     Irssi::print("Converting configuration, stage 2");
76
77     # Copy the "basic" settings.
78     foreach (qw(getter mode)) {
79         config_set(['getter'], $conf->{videosite}->{$_});
80     }
81
82     # Copy the per-getter/setter settings
83     foreach my $g (keys(%{$conf->{videosite}->{config}})) {
84         foreach (keys(%{$conf->{videosite}->{config}->{$g}->{option}})) {
85             config_set(['plugin', $g, $_], $conf->{videosite}->{config}->{$g}->{option}->{$_});
86         }
87     }
88
89     # Copy the connectors. The connectors themselves are copied as-is,
90     # the list of active connectors is copied under a different name,
91     # and a list of all existing connectors is created
92     my @connectors;
93
94     foreach my $c (keys(%{$conf->{videosite}->{connectors}})) {
95         push(@connectors, $c);
96         config_set(['connectors', $c, 'name'], $conf->{videosite}->{connectors}->{$c}->{name});
97         if (exists($conf->{videosite}->{connectors}->{$c}->{_immutable})) {
98             config_set(['connectors', $c, '_immutable'], $conf->{videosite}->{connectors}->{$c}->{_immutable});
99         }
100         foreach (qw(http https)) {
101             if (exists($conf->{videosite}->{connectors}->{$c}->{schemas}->{http})) {
102                 config_set(['connectors', $c, 'schemas', $_], $conf->{videosite}->{connectors}->{$c}->{schemas_}->{$_});
103             }
104         }
105     }
106     config_set(['active-connectors'], join(",", @{$conf->{connectorlist}}));
107     config_set(['defined-connectors'], join(",", @connectors));
108     config_set(['config-version'], '2');
109 }
110
111 #
112 # Reading a configuration value. Called by the core
113 #
114 sub config_get {
115     my $path = shift;
116     my $item = join('.', 'videosite', @{$path});
117     my $val;
118
119
120     Irssi::settings_add_str('videosite', $item, "\0");
121     $val = Irssi::settigs_get_str($item);
122
123     return ($val ne "\0")?$val:undef;
124 }
125
126 #
127 # Returns a true value if the config item exists
128 #
129 sub config_has {
130     my $path = shift;
131     my $item = join('.', 'videosite', @{$path});
132
133     Irssi::settings_add_str('videosite', $item, "\0");
134     return Irssi::settings_get_str ne "\0";
135 }
136
137 #
138 # Setting a configuration value. Called by the core
139 #
140 sub config_set {
141     my $path = shift;
142     my $value = shift;
143     my $item = join('.', 'videosite', @{$path});
144
145     Irssi::settings_add_str('videosite', $item, "\0");
146     Irssi::settings_set_str($item, $value);
147 }
148
149 #
150 # Delete a configuration value. Called by the core.
151 #
152 sub config_del {
153     my $path = shift;
154     my $item = join('.', 'videosite', @{$path});
155
156     Irssi::settings_remove($item);
157 }
158
159 #
160 # Return a color code. Called by the core
161 #
162 sub colorpair {
163     my ($fg, $bg) = @_;
164
165     Irssi::print(sprintf("Asked to convert (%s,%s) into irssi color codes", $fg, $bg));o
166
167     return '';
168 }
169
170 #
171 # Handle commands (/videosite ...)
172 #
173 sub videosite_hook {
174     my ($cmdline, $server, $witem) = @_;
175     my %event = (
176         message => $cmdline,
177         ewpf => sub { defined($evitem)?$evitem->print(@_):Irssi::print(@_) },
178     );
179
180     libvideosite::handle_command(\%event);
181 }
182
183 #
184 # Handle a received message
185 # Create an event structure and hand it off to libvideosite
186 #
187 sub message_hook {
188     my ($server, $msg, $nick, $userhost, $channel) = @_;
189     my $evitem = $server->window_item_find($channel);
190     my %event = (
191         message => $msg,
192         ewpf => sub { defined($evitem)?$evitem->print(@_):Irssi::print(@_) },
193     );
194
195     libvideosite::check_for_link(\%event);
196 }
197
198 sub videosite_reset {
199     unless(libvideosite::register_api({
200         io => sub { Irssi::print(@_) },
201         config_init => \&config_init,
202         config_get =>  \&config_get,
203         config_set => \&config_set,
204         config_has => \&config_has,
205         config_save => \&config_save,
206         config_del => \&config_del,
207         color => \&colorpair,
208         module_path => sub { return File::Spec->catfile(Irssi::get_irssi_dir(), 'scripts') },
209         quote => sub { s/%/%%/g; return $_ },
210         _debug => sub { 1 },
211     })) {
212         Irssi::print(sprintf("videosite API register failed: %s", $libvideosite::error));
213         return 0;
214     }
215
216     unless(libvideosite::init()) {
217         Irssi::print(sprintf("videosite init failed: %s", $libvideosite::error));
218         return 0;
219     }
220
221     return 1;
222 }
223
224 sub videosite_init {
225     # Find out the script directory, and add it to @INC.
226     # This is necessary to find libvideosite.pm
227
228     push(@INC, File::Spec->catfile(Irssi::get_irssi_dir(), 'scripts'));
229     load 'libvideosite';
230
231     if (videosite_reset()) {
232         signal_add_last("message public", sub { message_hook(@_) });
233         signal_add_last("message own_public", sub { message_hook($_[0], $_[1], undef, undef, $_[2]) });
234         signal_add_last("message private", sub { message_hooK($_[0], $_[1], $_[2], $_[3], $_[2]) });
235         signal_add_last("message own_private", sub { message_hook($_[0], $_[1], undef, undef, $_[2]) });
236         signal_add_last("message irc action", sub { message_hook(@_) });
237         signal_add_last("message irc own_action", sub { message_hook($_[0], $_[1], undef, undef, $_[2]) });
238
239         Irssi::command_bind('videosite', sub { videosite_hook(@_) });
240     }
241 }
242
243 videosite_init();