1 | use strict; |
---|
2 | use warnings; |
---|
3 | |
---|
4 | package BarnOwl::Message::Zulip; |
---|
5 | use base qw(BarnOwl::Message); |
---|
6 | |
---|
7 | use BarnOwl::Module::Zulip qw(default_realm); |
---|
8 | |
---|
9 | |
---|
10 | sub strip_realm { |
---|
11 | my $sender = shift; |
---|
12 | my $realm = BarnOwl::Module::Zulip::default_realm(); |
---|
13 | $sender =~ s/\@\Q$realm\E$//; |
---|
14 | return $sender; |
---|
15 | } |
---|
16 | |
---|
17 | sub context { |
---|
18 | return shift->class; |
---|
19 | } |
---|
20 | |
---|
21 | sub subcontext { |
---|
22 | return shift->instance; |
---|
23 | } |
---|
24 | |
---|
25 | sub pretty_sender { |
---|
26 | my ($m) = @_; |
---|
27 | return strip_realm($m->sender); |
---|
28 | } |
---|
29 | |
---|
30 | sub pretty_recipient { |
---|
31 | my ($m) = @_; |
---|
32 | return strip_realm($m->recipient); |
---|
33 | } |
---|
34 | |
---|
35 | sub private_recipient_list { |
---|
36 | my ($m) = @_; |
---|
37 | return split(/ /, $m->recipient); |
---|
38 | } |
---|
39 | |
---|
40 | sub class { return shift->{"class"}; } |
---|
41 | sub instance { return shift->{"instance"}; } |
---|
42 | sub realm { return shift->{"realm"}; } |
---|
43 | sub opcode { return shift->{"opcode"}; } |
---|
44 | sub long_sender { return shift->{"sender_full_name"}; } |
---|
45 | sub zid { return shift->{zid}; } |
---|
46 | |
---|
47 | sub replycmd { |
---|
48 | my $self = shift; |
---|
49 | if ($self->is_private) { |
---|
50 | return $self->replyprivate(1); |
---|
51 | } else { |
---|
52 | return BarnOwl::quote("zulip:write", "-c", $self->class, |
---|
53 | "-i", $self->instance); |
---|
54 | } |
---|
55 | } |
---|
56 | |
---|
57 | sub replysendercmd { |
---|
58 | my $self = shift; |
---|
59 | if ($self->is_private) { |
---|
60 | return $self->replyprivate(0); |
---|
61 | } else { |
---|
62 | return BarnOwl::quote("zulip:write", $self->sender); |
---|
63 | } |
---|
64 | } |
---|
65 | |
---|
66 | sub replyprivate { |
---|
67 | # Cases: |
---|
68 | # - me -> me: me |
---|
69 | # - me -> other: other |
---|
70 | # - (all) me -> other1, other2: other1, other2 |
---|
71 | # - (not) me -> other1, other2: error |
---|
72 | # - other -> me: other |
---|
73 | # - (all) other1 -> me, other2: other1, other2 |
---|
74 | # - (not) other1 -> me, other2: other1 |
---|
75 | my $self = shift; |
---|
76 | my $all = shift; |
---|
77 | my @recipients; |
---|
78 | if ($all) { |
---|
79 | @recipients = $self->private_recipient_list; |
---|
80 | } else { |
---|
81 | if ($self->sender eq BarnOwl::Module::Zulip::user()) { |
---|
82 | @recipients = $self->private_recipient_list; |
---|
83 | if (scalar(@recipients) > 1) { |
---|
84 | BarnOwl::error("Cannot reply privately to message to more than one recipient"); |
---|
85 | return; |
---|
86 | } |
---|
87 | } else { |
---|
88 | @recipients = $self->sender; |
---|
89 | } |
---|
90 | } |
---|
91 | my @filtered_recipients = grep { $_ ne BarnOwl::Module::Zulip::user() } @recipients; |
---|
92 | if (scalar(@filtered_recipients) == 0) { |
---|
93 | # Self must have been only recipient, so re-add it (one copy) |
---|
94 | @filtered_recipients = @recipients[0]; |
---|
95 | } |
---|
96 | return BarnOwl::quote("zulip:write", @filtered_recipients); |
---|
97 | } |
---|
98 | |
---|
99 | # Strip layers of "un" and ".d" from names |
---|
100 | sub base_name { |
---|
101 | my $name = shift; |
---|
102 | |
---|
103 | while($name =~ /(^un)/) { |
---|
104 | $name =~ s/(^un)//; |
---|
105 | } |
---|
106 | while($name =~ /\.d$/) { |
---|
107 | $name =~ s/(\.d$)//g; |
---|
108 | } |
---|
109 | return $name; |
---|
110 | } |
---|
111 | |
---|
112 | sub baseclass { |
---|
113 | my $self = shift; |
---|
114 | return base_name($self->class); |
---|
115 | } |
---|
116 | |
---|
117 | sub baseinstance { |
---|
118 | my $self = shift; |
---|
119 | return base_name($self->instance); |
---|
120 | } |
---|
121 | |
---|
122 | sub quote_for_filter { |
---|
123 | my $quote_chars = '!+*.?\[\]\^\\${}()|'; |
---|
124 | my $str = shift; |
---|
125 | return ($str =~ s/[$quote_chars]/\\$1/gr); |
---|
126 | } |
---|
127 | |
---|
128 | # This is intended to be a port of the Zephyr part of |
---|
129 | # owl_function_smartfilter from functions.c. |
---|
130 | sub smartfilter { |
---|
131 | my ($self, $inst, $related) = @_; |
---|
132 | my $filter; |
---|
133 | my @filter; |
---|
134 | if($self->is_private) { |
---|
135 | my @recips = $self->private_recipient_list; |
---|
136 | if(scalar(@recips) > 1) { |
---|
137 | BarnOwl::message("Smartnarrow for group personals not supported yet. Sorry :("); |
---|
138 | return ""; |
---|
139 | } else { |
---|
140 | my $person; |
---|
141 | if($self->direction eq "in") { |
---|
142 | $person = $self->sender; |
---|
143 | } else { |
---|
144 | $person = $self->recipient; |
---|
145 | } |
---|
146 | $filter = "zulip-user-$person"; |
---|
147 | # $person =~ s/\./\\./ |
---|
148 | $person =~ quote_for_filter($person); |
---|
149 | @filter = split / /, "( type ^Zulip\$ and filter personal and ( ( direction ^in\$ and sender ^${person}\$ ) or ( direction ^out\$ and recipient ^${person}\$ ) ) )"; |
---|
150 | } |
---|
151 | } else { |
---|
152 | my $class; |
---|
153 | my $instance; |
---|
154 | |
---|
155 | if($related) { |
---|
156 | $class = $self->baseclass; |
---|
157 | if($inst) { |
---|
158 | $instance = $self->baseinstance; |
---|
159 | } |
---|
160 | $filter = "related-"; |
---|
161 | } else { |
---|
162 | $class = $self->class; |
---|
163 | if($inst) { |
---|
164 | $instance = $self->instance; |
---|
165 | } |
---|
166 | $filter = ""; |
---|
167 | } |
---|
168 | $filter .= "class-$class"; |
---|
169 | if($inst) { |
---|
170 | $filter .= "-instance-$instance"; |
---|
171 | } |
---|
172 | $class = quote_for_filter($class); |
---|
173 | # TK deal with filter already existing |
---|
174 | @filter = (($related ? ("class", "^(un)*${class}(\\.d)*\$") : ("class", "^${class}\$"))); |
---|
175 | if($inst) { |
---|
176 | $instance = quote_for_filter($instance); |
---|
177 | push @filter, ($related ? (qw{ and ( instance }, "^(un)*${instance}(\\.d)*\$", ")") : (qw{ and ( instance }, "^${instance}\$", ")")); |
---|
178 | } |
---|
179 | } |
---|
180 | BarnOwl::command("filter", $filter, @filter); |
---|
181 | return $filter; |
---|
182 | } |
---|
183 | |
---|
184 | 1; |
---|