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

240
LINES

< > BotCompany Repo | #1026246 // Imager Thought Bot

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Libraryless. Click here for Pure Java version (13456L/95K).

!7

sS dbBotID = #1026247;

static Env env;
static new ThreadLocal<Session> session;
static new ThreadLocal<Out> out;

sclass Out {
  S buttonsIntro;
  LS buttons;
  S placeholder;
  S defaultInput;
}

sbool testFunctions = false;

static interface Env {
  void sayAsync(S session, S msg);
}

concept Session {
  S cookie;
  S language;
  S lastQuestion;
  FormInFlight form, lastForm;
  
  void cancelForm {
    cset(this, lastForm := form, form := null);
  }
  
  S language() { ret or2(language, 'en); }
}

sclass FormStep {
  S key;
  S displayText, desc;
  S defaultValue;
  S placeholder; // null for same as displayText, "" for none
  LS buttons;
  S value;
  
  void update(Runnable onChange) {}
}

sclass FormInFlight {
  S hashTag;
  new L<FormStep> steps;
  int stepIndex; // in steps list
  
  FormStep currentStep() {
    ret get(steps, stepIndex);
  }
  
  void update(Runnable onChange) {
    if (currentStep() != null) currentStep().update(onChange);
  }
  
  S complete() { ret "Form complete"; }
  S cancel() { ret "Request cancelled"; }
  
  bool shouldCancel() { false; }
}

sclass MainForm > FormInFlight {
  FormStep stepInterested, stepMailAddress, stepDevice, stepConfirm;
  
  *() {
    hashTag = "#mainForm";
  }
  
  bool shouldCancel() {
    ret isNo(stepInterested.value);
  }
}

sbool debug;

svoid setSession(S cookie, SS params) {
  session.set(uniq_sync(Session, +cookie));
  S lang = mapGet(params, 'language);
  if (nempty(lang))
    cset(session!, language := lang);
  S lang_default = mapGet(params, 'language_default);
  if (nempty(lang_default)) {
    print("lang_default=" + lang_default + ", have: " + session->language);
    if (empty(session->language)) {
      print("Setting language.");
      cset(session!, language := lang_default);
    }
  }
}

svoid clearSession(S cookie) {
  deleteConcepts(Session, +cookie);
}

p {
  db();
  
  // for testing on desktop
  if (isMain()) { veryBigConsole(); bot(); }
}

sS returnQuestion(S q) {
  cset(session!, lastQuestion := q);
  ret q;
}

sS answer(S s) {
  if (session! == null) setSession("default", new Map);
  out.set(new Out);
  if (creator() == null) if "debug" set debug;
  
  S lq = session->lastQuestion;
  cset(session!, lastQuestion := null);
  
  FormInFlight form = session->form;
  if (form != null && form.currentStep() != null) {
    if (eqicOneOf(s, "cancel", "Abbrechen", unicode_crossProduct())) {
      S answer = form.cancel();
      session->cancelForm();
      ret answer;
    }
    else if (eqicOneOf(s, "back", "zurück", unicode_undoArrow()) && form.stepIndex > 0) {
      --form.stepIndex;
      session->change();
      ret deliverAnswerAndFormStep("");
    } else {
      FormStep step = form.currentStep();
      if (nempty(step.buttons) && !cic(step.buttons, s))
        ret deliverAnswerAndFormStep(de() ? "Bitte wählen Sie eine Option!" : "Please choose an option.");
        
      step.value = s;
      ++form.stepIndex;
      session->change();
      if (form.currentStep() == null) {
        S answer = form.complete();
        session->cancelForm();
        ret answer;
      }
      ret deliverAnswerAndFormStep("");
    }
  }
  
  if (testFunctions) {
    if (eq(lq, "Would you like some tea?")) {
      if "yes" ret "Here's your tea.";
      if "no" ret "Very well then.";
    }
    
    if "test buttons" {
      out->buttons = ll("Yes", "No");
      ret returnQuestion("Would you like some tea?");
    }
    
    if "say something later" {
      if (env == null) ret("No env");
      final S mySession = session->cookie;
      thread {
        sleepSeconds(5);
        env.sayAsync(mySession, "Here it is.");
      }
      ret "OK, will do it in 5 seconds";
    }
  }
  
  // call special input processors
  
  try answer processURLInInput(s);

  // get answer from bot, switch language
  
  O bot = dbBot();
  S a = (S) call(bot, 'answer, s, session->language());
  S lang = cast getThreadLocal(((ThreadLocal) get(bot, 'language_out)));
  if (nempty(lang)) cset(session!, language := lang);
  
  S a2 = replaceAll(a, "\\s*#mainForm\\b", "");
  if (neq(a, a2)) {
    form = new MainForm;
    print("Made form for cookie " + session->cookie + ": " + sfu(form));
    cset(session!, +form);
  }
  
  ret deliverAnswerAndFormStep(a2);
}

sS deliverAnswerAndFormStep(S answer) {
  FormInFlight form = session->form;
  if (form == null) ret answer;
  
  form.update(r { session->change() });
  if (form.shouldCancel()) {
    session->cancelForm();
    ret answer;
  }

  if (form.currentStep() == null)  ret answer;
  
  FormStep step = form.currentStep();
  if (empty(answer))
    answer = step.displayText;
  else
    out->buttonsIntro = step.displayText;
  out->placeholder = or(step.placeholder, step.displayText);
  print("Step " + form.stepIndex + ": " + sfu(step));
  out->defaultInput = or2(step.value, step.defaultValue);
  out->buttons = cloneList(step.buttons);
  if (form.stepIndex > 0) out->buttons.add(de() ? "Zurück" : "Back");
  out->buttons.add(de() ? "Abbrechen" : "Cancel");
  ret answer;
}

sS initialMessage() {
  print("initialMessage, lang=" + session->language());
  ret or2(answer("#greeting"), "Hello");
}

sO dbBot() {
  ret getBot(dbBotID);
}

sbool de() {
  ret eqic(session->language(), "de");
}

sbool botOn() {
  ret isTrue(call(dbBot(), "botOn"));
}

sbool botAutoOpen() {
  ret isTrue(call(dbBot(), "botAutoOpen"));
}

sS processURLInInput(S s) {
  LS urls = regexpAllMatches(urlFinderRegexp(), s);
  if (empty(urls)) null;
  ret "URLs found:\n" + lines(urls);
}

Author comment

Began life as a copy of #1026222

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: #1026246
Snippet name: Imager Thought Bot
Eternal ID of this version: #1026246/5
Text MD5: ae033e2ba4c3db57cf156a9c1483bfcd
Transpilation MD5: 499060f5ed0d17531c60f6b49e9ae3be
Author: stefan
Category: javax / a.i.
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-12-09 19:41:32
Source code size: 5764 bytes / 240 lines
Pitched / IR pitched: No / No
Views / Downloads: 249 / 1025
Version history: 4 change(s)
Referenced in: #1026127 - Auto-Reload Eleu Modules On Server
#1026248 - Imager Chat Bot
#1026321 - abots.space Thought Bot