From: Adam S. <as...@ko...> - 2019-04-14 08:41:55
|
If a jabber:x:oob message is received with a URL that looks like an image, the image is fetched and displayed. If it can't be displayed, Image: url is shown instead. I'm not quite sure about moving jabber-char-print-url to jabber-body-printers, but I don't think it makes sense to show it if displaying the image succeeds. However, if there is a URL, that can't be displayed, maybe the body should be shown? Hm. In the examples I've seen, the message looks like: <message from="vi...@ko.../pidgin" to="as...@ko..." type="chat" id="purple4fb6fb94"> <archived by="koldfront.dk" xmlns="urn:xmpp:mam:tmp" id="1555194815542627"/> <stanza-id by="koldfront.dk" xmlns="urn:xmpp:sid:0" id="1555194815542627"/> <body>https://koldfront.dk/xmpp/virgil/8ze1C6CGD1hvWQhbl4cYNzDYrAb19wjbFX7IkXZ3/x-face.png</body> <x xmlns="jabber:x:oob"> <url>https://koldfront.dk/xmpp/virgil/8ze1C6CGD1hvWQhbl4cYNzDYrAb19wjbFX7IkXZ3/x-face.png</url> </x> </message> So the body is redundant when the jabber:x:oob url is handled. --- I have updated the patch to handle errors when fetching/creating the image, it will now properly display Image: url, and I have added the max-width and max-height as customizable values. Also, webp is now in the regex. jabber-chat.el | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/jabber-chat.el b/jabber-chat.el index e2fd607..60e91f7 100644 --- a/jabber-chat.el +++ b/jabber-chat.el @@ -139,6 +139,16 @@ These fields are available: :type 'string :group 'jabber-chat) +(defcustom jabber-chat-image-max-width 800 + "The maximum width of images shown in chats." + :type 'integer + :group 'jabber-chat) + +(defcustom jabber-chat-image-max-height 400 + "The maximum height of images shown in chats." + :type 'integer + :group 'jabber-chat) + (defface jabber-chat-prompt-local '((t (:foreground "blue" :weight bold))) "face for displaying the chat prompt for what you type in" @@ -177,7 +187,6 @@ These fields are available: (defvar jabber-chat-printers '(jabber-chat-print-subject jabber-chat-print-body - jabber-chat-print-url jabber-chat-goto-address) "List of functions that may be able to print part of a message. Each function receives these arguments: @@ -187,7 +196,9 @@ WHO :local or :foreign, for sent or received stanza, respectively MODE :insert or :printp. For :insert, insert text at point. For :printp, return non-nil if function would insert text.") -(defvar jabber-body-printers '(jabber-chat-normal-body) +(defvar jabber-body-printers '(jabber-chat-print-image + jabber-chat-print-url + jabber-chat-normal-body) "List of functions that may be able to print a body for a message. Each function receives these arguments: @@ -630,6 +641,51 @@ If DONT-PRINT-NICK-P is true, don't include nickname." (format "%s <%s>" desc url)))))) foundp)) +(defun jabber-chat-download-image (url) + "Download image from URL and return as image" + ;;; Maybe do a HEAD request and check Content-Type: instead? + (when (string-match "^https?://.*\\.\\(png\\|jpg\\|jpeg\\|gif\\|webp\\)$" url) + (condition-case nil + (let ((image-buffer (url-retrieve-synchronously url))) + (when image-buffer + (with-current-buffer image-buffer + (goto-char (point-min)) + (re-search-forward "^$" nil 'move) + (forward-char) + (delete-region (point-min) (point)) + (let ((image (create-image (buffer-string) nil t :max-width jabber-chat-image-max-width :max-height jabber-chat-image-max-height))) + ; I can't figure out how to use max-width and max-height, + ; as width and height are set, and overrides them: + (let ((width (image-property image :width)) + (height (image-property image :height))) + (setf (image-property image :width) nil) + (setf (image-property image width) nil) + (setf (image-property image :height) nil) + (setf (image-property image height) nil)) + image)))) + (error nil)))) + +(defun jabber-chat-print-image (xml-data who mode) + "Print images provided in jabber:x:oob namespace." + (let ((foundp nil)) + (dolist (x (jabber-xml-node-children xml-data)) + (when (and (listp x) (eq (jabber-xml-node-name x) 'x) + (string= (jabber-xml-get-attribute x 'xmlns) "jabber:x:oob")) + (setq foundp t) + + (when (eql mode :insert) + (let ((url (car (jabber-xml-node-children + (car (jabber-xml-get-children x 'url)))))) + (let ((image (jabber-chat-download-image url))) + (if image + (progn + (insert-image image url) + (insert "\n")) + (insert (jabber-propertize + "Image: " 'face 'jabber-chat-prompt-system) + url))))))) + foundp)) + (defun jabber-chat-goto-address (xml-data who mode) "Call `goto-address' on the newly written text." (when (eq mode :insert) -- 2.20.1 -- "Everything needs to change. Adam Sjøgren And it has to start today." as...@ko... |