<commit_before>(defpackage :potato.web.channel
  (:use :cl :potato :potato.common :potato.web))

(in-package :potato.web.channel)

(declaim #.potato.common::*compile-decl*)

(defparameter *max-history-length* 200
  "The maximum number of messages returned from a call to /history")

(defun show-channel-screen (channel-id url dev)
  (potato.core:with-authenticated-user ()
    (let* ((user (potato.core:current-user))
           (channel (potato.core:load-channel-with-check channel-id :if-not-joined :join))
           (group (potato.core:load-group-with-check (potato.core:channel/group channel)))
           (domain (potato.core:load-domain-with-check (potato.core:group/domain group) user))
           (domain-tree (potato.web:make-group-channel-tree-for-user-and-domain domain user)))
      ;; When loading the main channel page, clear all outstanding
      ;; notifications for that channel. We can simply assume that the
      ;; user will catch up on all new messages when loading the page.
      (potato.user-notification:mark-notifications-for-user-channel user channel)
      ;;
      (lofn:show-template-stream "channel.tmpl"
                                 `((:debug            . ,*debug*)
                                   (:channel-id       . ,(potato.core:channel/id channel))
                                   (:channel-name     . ,(potato.core:channel/name channel))
                                   (:channel-url      . ,url)
                                   (:user-id          . ,(potato.core:user/id user))
                                   (:email            . ,(potato.core:user/primary-email user))
                                   (:user-description      . ,(potato.core:user/description user))
                                   (:group            . ,(potato.core:group/id group))
                                   (:group-name       . ,(potato.core:group/name group))
                                   (:domain-id        . ,(potato.core:group/domain group))
                                   (:domain-name      . ,(potato.core:domain/name domain))
                                   (:admin-p          . ,(potato.core:user-is-admin-in-group-p group user))
                                   (:group-type       . ,(potato.core:group/type group))
                                   (:domain-tree      . ,domain-tree)
                                   (:current-build-id . ,potato:*build-id*)
                                   (:s3-access-key    . ,*s3-browser-access-key*)
                                   (:s3-endpoint      . ,*s3-endpoint*)
                                   (:s3-bucket        . ,*s3-bucket*)
                                   (:websocket-url    . ,*external-websocket-listen-address*)
                                   (:dev              . ,dev)
                                   (:default-upload-location . ,potato.upload:*default-upload-location*))))))

(defmacro %define-channel-screen (name url dev)
  `(potato.core:define-handler-fn-login (,name ,(concatenate 'string url "/([a-z0-9]+)") t (channel-id))
     (show-channel-screen channel-id ,url ,dev)))

(%define-channel-screen channel-screen "/channel" nil)
(%define-channel-screen channel-dev-screen "/channel-dev" t)

(potato.core:define-handler-fn-login (channel-by-domain-and-nickname-screen "/c/([^/]+)/([^/]+)" t
                                                                            (domain-nickname channel-nickname))
  (handler-case
      (let ((cid (potato.core:find-channel-id-for-nicknames domain-nickname channel-nickname)))
        (show-channel-screen cid "/channel" "channel.tmpl"))
    (clouchdb:document-missing () (potato.core:raise-not-found-error "No such channel"))))

(potato.core:define-json-handler-fn-login (history-screen "/history" data nil ())
  (potato.core:with-authenticated-user ()
    (let ((channel (potato.core:load-channel-with-check (st-json:getjso "channel" data)))
          (num-messages (min (or (st-json:getjso "num_messages" data) *max-history-length*) *max-history-length*))
          (start (st-json:getjso "start" data)))
      (log:trace "Loading history for channel: ~s, num-messages: ~s, start: ~s"
                 (potato.core:channel/id channel) num-messages start)
      (let ((messages (potato.core:load-message-log channel num-messages (if (eq start :null) nil start))))
        (st-json:jso "messages" (mapcar (lambda (v)
                                          (potato.core:message-cd->json v :html (potato.core:current-user)))
                                        messages))))))

(potato.core:define-json-handler-fn-login (load-message-range-screen "/range" data nil ())
  (potato.core:with-authenticated-user ()
    (let* ((message-id (st-json:getjso "message" data))
           (num-rows (or (st-json:getjso "rows" data) 5)))
      (unless (< 1 num-rows 50)
        (potato.core:raise-web-parameter-error "rows parameter out of range"))
      (let ((range (potato.core:load-message-range-with-check message-id num-rows)))
        (st-json:jso "messages" (mapcar (lambda (v)
                                          (potato.core:message-cd->json v :html (potato.core:current-user)))
                                        range))))))

(defun try-send-channel (data text)
  (json-bind ((cid "channel")) data
    (potato.workflow:send-message-to-channel (potato.core:current-user)
                                             (potato.core:load-channel-with-check cid)<commit_msg>The /d/ shorthand for channel links should not use dev mode<commit_after>(defpackage :potato.web.channel
  (:use :cl :potato :potato.common :potato.web))

(in-package :potato.web.channel)

(declaim #.potato.common::*compile-decl*)

(defparameter *max-history-length* 200
  "The maximum number of messages returned from a call to /history")

(defun show-channel-screen (channel-id url dev)
  (potato.core:with-authenticated-user ()
    (let* ((user (potato.core:current-user))
           (channel (potato.core:load-channel-with-check channel-id :if-not-joined :join))
           (group (potato.core:load-group-with-check (potato.core:channel/group channel)))
           (domain (potato.core:load-domain-with-check (potato.core:group/domain group) user))
           (domain-tree (potato.web:make-group-channel-tree-for-user-and-domain domain user)))
      ;; When loading the main channel page, clear all outstanding
      ;; notifications for that channel. We can simply assume that the
      ;; user will catch up on all new messages when loading the page.
      (potato.user-notification:mark-notifications-for-user-channel user channel)
      ;;
      (lofn:show-template-stream "channel.tmpl"
                                 `((:debug            . ,*debug*)
                                   (:channel-id       . ,(potato.core:channel/id channel))
                                   (:channel-name     . ,(potato.core:channel/name channel))
                                   (:channel-url      . ,url)
                                   (:user-id          . ,(potato.core:user/id user))
                                   (:email            . ,(potato.core:user/primary-email user))
                                   (:user-description      . ,(potato.core:user/description user))
                                   (:group            . ,(potato.core:group/id group))
                                   (:group-name       . ,(potato.core:group/name group))
                                   (:domain-id        . ,(potato.core:group/domain group))
                                   (:domain-name      . ,(potato.core:domain/name domain))
                                   (:admin-p          . ,(potato.core:user-is-admin-in-group-p group user))
                                   (:group-type       . ,(potato.core:group/type group))
                                   (:domain-tree      . ,domain-tree)
                                   (:current-build-id . ,potato:*build-id*)
                                   (:s3-access-key    . ,*s3-browser-access-key*)
                                   (:s3-endpoint      . ,*s3-endpoint*)
                                   (:s3-bucket        . ,*s3-bucket*)
                                   (:websocket-url    . ,*external-websocket-listen-address*)
                                   (:dev              . ,dev)
                                   (:default-upload-location . ,potato.upload:*default-upload-location*))))))

(defmacro %define-channel-screen (name url dev)
  `(potato.core:define-handler-fn-login (,name ,(concatenate 'string url "/([a-z0-9]+)") t (channel-id))
     (show-channel-screen channel-id ,url ,dev)))

(%define-channel-screen channel-screen "/channel" nil)
(%define-channel-screen channel-dev-screen "/channel-dev" t)

(potato.core:define-handler-fn-login (channel-by-domain-and-nickname-screen "/d/([^/]+)/([^/]+)" t
                                                                            (domain-nickname channel-nickname))
  (handler-case
      (let ((cid (potato.core:find-channel-id-for-nicknames domain-nickname channel-nickname)))
        (show-channel-screen cid "/channel" nil))
    (clouchdb:document-missing () (potato.core:raise-not-found-error "No such channel"))))

(potato.core:define-json-handler-fn-login (history-screen "/history" data nil ())
  (potato.core:with-authenticated-user ()
    (let ((channel (potato.core:load-channel-with-check (st-json:getjso "channel" data)))
          (num-messages (min (or (st-json:getjso "num_messages" data) *max-history-length*) *max-history-length*))
          (start (st-json:getjso "start" data)))
      (log:trace "Loading history for channel: ~s, num-messages: ~s, start: ~s"
                 (potato.core:channel/id channel) num-messages start)
      (let ((messages (potato.core:load-message-log channel num-messages (if (eq start :null) nil start))))
        (st-json:jso "messages" (mapcar (lambda (v)
                                          (potato.core:message-cd->json v :html (potato.core:current-user)))
                                        messages))))))

(potato.core:define-json-handler-fn-login (load-message-range-screen "/range" data nil ())
  (potato.core:with-authenticated-user ()
    (let* ((message-id (st-json:getjso "message" data))
           (num-rows (or (st-json:getjso "rows" data) 5)))
      (unless (< 1 num-rows 50)
        (potato.core:raise-web-parameter-error "rows parameter out of range"))
      (let ((range (potato.core:load-message-range-with-check message-id num-rows)))
        (st-json:jso "messages" (mapcar (lambda (v)
                                          (potato.core:message-cd->json v :html (potato.core:current-user)))
                                        range))))))

(defun try-send-channel (data text)
  (json-bind ((cid "channel")) data
    (potato.workflow:send-message-to-channel (potato.core:current-user)
                                             (potato.core:load-channel-with-check cid)
{'fraction_non_alphanumeric': 0.14309135622552144, 'fraction_numerical': 0.0027324892977502505, 'mean_word_length': 1.7340637450199203, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 64, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4110671', 'n_tokens_mistral': 3205, 'n_tokens_neox': 3082, 'n_words': 611}