Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

287
LINES

< > BotCompany Repo | #1025817 // Katherine backup before synonyms

JavaX source code (Dynamic Module) - run with: Stefan's OS

1  
!7
2  
3  
cmodule NLRulesBot extends DynTalkBot2<.ByServer> {
4  
  void init {
5  
    super.init();
6  
    makeByServer = () -> new ByServer;
7  
    useAGIBlueForDropPunctuation = false;
8  
    preprocessAtSelfToMyName = false;
9  
    dropPunctuation = false;
10  
    print("Total rules in all guilds: " + totalRuleCount());
11  
  }
12  
  
13  
  sclass Rule {
14  
    GlobalID globalID = aGlobalIDObj();
15  
    S text;
16  
    
17  
    *() {} *(S *text) {}
18  
  }
19  
  
20  
  S renderRule(Rule r) {
21  
    ret r == null ? null : "Rule " + r.globalID + ": " + r.text;
22  
  }
23  
24  
  class ByServer extends DynTalkBot2<NLRulesBot.ByServer>.ByServer {
25  
    new L<Rule> rules;
26  
    new Set<Long> priorityChannels; // where we always respond
27  
    bool enableMagicQuotes = true;
28  
    
29  
    new SimpleFactStore factStore;
30  
    
31  
    synchronized S processSimplifiedLine(S s, O... _) {
32  
      try answer super.processSimplifiedLine(s, _);
33  
      
34  
      try answer factStore_cmds(factStore, s, authed(_));
35  
      try answer philosophyBotWithFactStore_discordAnswer(
36  
      ai_weightChangeBot_theory(), factStore, s, _);
37  
      
38  
      long channelID = longPar channelID(_);
39  
      
40  
      new Matches m;
41  
      S s2 = dropMyPrefixOrNull(s);
42  
      if (s2 != null) s = s2;
43  
      else if (!contains(priorityChannels, channelID)) null;
44  
      optPar Message msg;
45  
      Message.Attachment attachment = msg == null ? null : first(msg.getAttachments());
46  
      if (attachment != null) {
47  
        long guildID = idForByServer(this);
48  
        File file = prepareCacheProgramFile(guildID + "/" + attachment.getFileName());
49  
        print("Downloading attachment: " + file);
50  
        deleteFile(file);
51  
        if (!attachment.download(file)) ret "Couldn't download attachment";
52  
        LS lines = tlft(loadTextFile(file));
53  
        print("First line: " + first(lines));
54  
        if (!swic(first(lines), "rule ")) print("Ignoring attachment");
55  
        else {
56  
          new LPairS toImport; // (globalID, text)
57  
          for (S line : lines) {
58  
            LS l = regexpICFullMatch_groups("Rule ([a-z]+):(.*)$", line);
59  
            if (nempty(l))
60  
              toImport.add(listToPair(l));
61  
          }
62  
          S found = "Found " + nRules(toImport) + " in attachment";
63  
          
64  
          int oldCount = l(rules);
65  
          Map<GlobalID, Rule> existing = indexByField globalID(rules);
66  
          int updated = 0, added = 0;
67  
          for (PairS rule : toImport) {
68  
            GlobalID id = GlobalID(rule.a);
69  
            S text = trim(rule.b);
70  
            Rule r = existing.get(id);
71  
            if (r == null) {
72  
              r = new Rule(text);
73  
              r.globalID = id;
74  
              rules.add(r);
75  
              existing.put(id, r);
76  
              ++added;
77  
            } else if (neq(r.text, text)) {
78  
              r.text = text;
79  
              ++updated;
80  
            }
81  
          }
82  
          
83  
          if (added+updated > 0) change();
84  
          ret found + ". Had: " + oldCount + ". Added: " + added + ". Updated: " + updated + ". New count: " + l(rules);
85  
        }
86  
        
87  
      }
88  
89  
      // duplicated patterns go here
90  
      if "on * say *|on * or * say *|on keyword * and * say *|on keyword * or * say *|on keyword * say *|on *, image-google X|on *, google X|when <*> comes online, say *|on bot keyword * and keyword *, say *" {
91  
        Rule r = firstWhereIC(rules, text := s);
92  
        if (r != null) ret "Rule exists: " + r.globalID;
93  
        rules.add(r = new Rule(s));
94  
        change();
95  
        ret "Rule added with ID " + r.globalID;
96  
      }
97  
      
98  
      if "rules"
99  
        ret or2(lines(map(r -> renderRule(r), rules)), "No rules defined yet");
100  
        
101  
      if "rules as file" {
102  
        uploadFileInChannel(channelID,
103  
          toUtf8(lines(map(r -> renderRule(r), rules))),
104  
          genericTextFileName(), null, null);
105  
        null;
106  
      }
107  
108  
      if "delete rule *|delete rule with id *" {
109  
        try answer checkAuth(_);
110  
        Rule r = firstWhere(rules, globalID := GlobalID($1));
111  
        if (r == null) ret "Rule " + $1 + " not found";
112  
        rules.remove(r);
113  
        change();
114  
        ret "Rule deleted, " + nRule(rules) + " remain";
115  
      }
116  
      
117  
      if "delete all rules" {
118  
        appendToTextFile(programFile("backups.txt"), guildStructure());
119  
        try answer checkAuth(_);
120  
        rules.clear();
121  
        change();
122  
        ret "All rules deleted";
123  
      }
124  
      
125  
      if "priority channel on" {
126  
        try answer checkAuth(_);
127  
        priorityChannels.add(channelID); change();
128  
        ret "OK";
129  
      }
130  
131  
      if "priority channel off" {
132  
        try answer checkAuth(_);
133  
        priorityChannels.remove(channelID); change();
134  
        ret "OK";
135  
      }
136  
      
137  
      if "disable magic quotes" {
138  
        try answer checkAuth(_);
139  
        enableMagicQuotes = false; change();
140  
        ret "OK";
141  
      }
142  
143  
      if (eqic(s, "help"))
144  
        ret ltrim([[
145  
I execute simple English rules.
146  
147  
Stuff to say.
148  
@me `on "hello bot" say "who are you"`
149  
@me `on keyword "time" say "it is always time for a tea"`
150  
@me `on "what is X" google X`
151  
@me `on "show me X" image-google X`
152  
@me `on bot keyword "game" and keyword "sure" say "let's play tic tac toe"`
153  
@me `when @user comes online, say "hello friend"`
154  
@me `rules` / `rules as file` - list rules
155  
@me `delete rule abcdefghijkl` - delete rule with ID
156  
@me `priority channel on` - respond to every msg
157  
@me `priority channel off` - respond to msgs with my name only
158  
@me `masters` / `add master <username>` / `delete master <username>`
159  
@me `help` / `support` / `source code`
160  
@me `download` - download my brain for this guild
161  
162  
To fill me with rules, just upload the file you got from `rules as file` to the channel.
163  
164  
[Bot made by https://BotCompany.de]
165  
  ]]).replace("@me", atSelf());
166  
  
167  
      // find rule to execute
168  
      
169  
      new LinkedHashSet<S> outs;
170  
      
171  
      for (Rule r : rules) pcall {
172  
        // IMPORTANT: patterns are duplicated above
173  
        
174  
        if (match("on * say *", r.text, m)) {
175  
          S in = $1, out = $2;
176  
          if (match(in, s))
177  
            outs.add(rewrite(out, _));
178  
        }
179  
        
180  
        if (match("on * or * say *", r.text, m)) {
181  
          S in1 = $1, in2 = $2, out = $3;
182  
          if (match(in1, s) || match(in2, s))
183  
            outs.add(rewrite(out, _));
184  
        }
185  
        
186  
        if (match("on keyword * and * say *", r.text, m)) {
187  
          S in1 = $1, in2 = $2, out = $3;
188  
          if (find3(in1, s) && find3(in2, s))
189  
            outs.add(rewrite(out, _));
190  
        }
191  
        
192  
        if (match("on keyword * or * say *", r.text, m)) {
193  
          S in1 = $1, in2 = $2, out = $3;
194  
          if (find3(in1, s) || find3(in2, s))
195  
            outs.add(rewrite(out, _));
196  
        }
197  
        
198  
        if (match("on bot keyword * and keyword *, say *", r.text, m)) {
199  
          ISaid lastSaid = lastSaidInChannel.get(channelID);
200  
          if (lastSaid != null) {
201  
            S in1 = $1, in2 = $2, out = $3;
202  
            if (find3(in1, lastSaid.text) && find3(in2, s))
203  
              outs.add(rewrite(out, _));
204  
          }
205  
        }
206  
207  
        if (match("on keyword * say *", r.text, m)) {
208  
          S in = $1, out = $2;
209  
          if (find3(in, s))
210  
            outs.add(rewrite(out, _));
211  
        }
212  
        
213  
        if (match("on *, image-google X", r.text, m))
214  
          if (flexMatchIC(replaceWord($1, "X", "*"), s, m)) {
215  
            bool nsfw = discord_isNSFWChannel_gen(optPar channel(_));
216  
            print(+nsfw);
217  
            BufferedImage img = nsfw ? quickVisualize_nsfw($1) : quickVisualize($1);
218  
            if (img == null) ret "No image found, sorry!";
219  
            postImage(paramsToMap(_), uploadToImageServer(img, $1));
220  
          }
221  
          
222  
        if (match("on *, google X", r.text, m))
223  
          if (flexMatchIC(replaceWord($1, "X", "*"), s, m)) {
224  
            bool nsfw = discord_isNSFWChannel_gen(optPar channel(_));
225  
            print(+nsfw);
226  
            ret discord_google($1, results := 1, safeSearch := !nsfw);
227  
          }
228  
      }
229  
      
230  
      if "download" {
231  
        optPar Guild guild;
232  
        optPar MessageChannel channel;
233  
        ret serveGuildBackup(channel, guild,
234  
          structure_nullingInstancesOfClass(_getClass(module()), ByServer.this));
235  
      }
236  
      
237  
      if "stats"
238  
        ret "I have " + nRules(rules);
239  
      
240  
      try answer random(outs);
241  
      
242  
      if (enableMagicQuotes)
243  
        try answer answer_magicQuoteInput(s, useTranspiled := true);
244  
      null;
245  
    }
246  
    
247  
    S rewrite(S answer, O... _) {
248  
      if (containsIC(answer, "<user>")) {
249  
        optPar S name;
250  
        if (empty(name)) name = discord_optParUserName(_);
251  
        if (nempty(name))
252  
          answer = replaceIC(answer, "<user>", name);
253  
      }
254  
      ret answer;
255  
    }
256  
    
257  
    void onOnlineStatusChange(UserUpdateOnlineStatusEvent e) {
258  
      User user = e.getMember().getUser();
259  
      print("User status change: " + user + " " + e.getOldValue() + " -> " + e.getNewValue());
260  
      
261  
      // only react to user coming online
262  
      if (e.getOldValue() != OnlineStatus.OFFLINE) ret;
263  
      
264  
      long id = user.getIdLong();
265  
      
266  
      new LinkedHashSet<S> outs;
267  
      new Matches m;
268  
269  
      for (Rule r : rules) pcall {
270  
        // IMPORTANT: patterns are duplicated above
271  
        
272  
        if (match("when <*> comes online, say *", r.text, m)) {
273  
          long _id = parseLongOpt($1);
274  
          S out = $2;
275  
          if (id == _id)
276  
            outs.add(rewrite(out, name := user.getName()));
277  
        }
278  
      }
279  
      
280  
      postInChannel(preferredChannelID, random(outs));
281  
    }
282  
  }
283  
  
284  
  long totalRuleCount() {
285  
    ret intSumAsLong(map(syncCloneValues(dataByServer), bs -> l(bs.rules)));
286  
  }
287  
}

Author comment

Began life as a copy of #1025624

download  show line numbers  debug dex  old transpilations   

Travelled to 6 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1025817
Snippet name: Katherine backup before synonyms
Eternal ID of this version: #1025817/1
Text MD5: 8b3cd85b7f650af99bac87321ba25c02
Author: stefan
Category: javax
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-10-22 21:50:26
Source code size: 9756 bytes / 287 lines
Pitched / IR pitched: No / No
Views / Downloads: 196 / 207
Referenced in: [show references]