source: perl/modules/Zulip/lib/BarnOwl/Message/Zulip.pm @ 51ce84b

Last change on this file since 51ce84b was 51ce84b, checked in by Adam Glasgall <glasgall@mit.edu>, 8 years ago
grody but functional smartfilter support for names with spaces
  • Property mode set to 100644
File size: 4.5 KB
Line 
1use strict;
2use warnings;
3
4package BarnOwl::Message::Zulip;
5use base qw(BarnOwl::Message);
6
7use BarnOwl::Module::Zulip qw(default_realm);
8
9
10sub 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
17sub context {
18    return shift->class;
19}
20
21sub subcontext {
22    return shift->instance;
23}
24
25sub pretty_sender {
26    my ($m) = @_;
27    return strip_realm($m->sender);
28}
29
30sub pretty_recipient {
31    my ($m) = @_;
32    return strip_realm($m->recipient);
33}
34
35sub private_recipient_list {
36    my ($m) = @_;
37    return split(/ /, $m->recipient);
38}
39
40sub class       { return shift->{"class"}; }
41sub instance    { return shift->{"instance"}; }
42sub realm       { return shift->{"realm"}; }
43sub opcode       { return shift->{"opcode"}; }
44sub long_sender        { return shift->{"sender_full_name"}; }
45sub zid { return shift->{zid}; }
46
47sub 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
57sub 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
66sub 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
100sub 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
112sub baseclass {
113    my $self = shift;
114    return base_name($self->class);
115}
116
117sub baseinstance {
118    my $self = shift;
119    return base_name($self->instance);
120}
121
122sub 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.
130sub 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
1841;
Note: See TracBrowser for help on using the repository browser.