Skip to content

Commit

Permalink
add img_data to EmailBody, update email_topic.py and email-topic-clie…
Browse files Browse the repository at this point in the history
…nt.l
  • Loading branch information
k-okada committed Jul 27, 2022
1 parent f6039ea commit 8d59a2e
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 22 deletions.
20 changes: 19 additions & 1 deletion jsk_robot_common/jsk_robot_startup/euslisp/email-topic-client.l
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
(ros::load-ros-manifest "jsk_robot_startup")

(require :base64 "lib/llib/base64.l")

(defun init-mail ()
(ros::advertise "email" jsk_robot_startup::Email 1)
(ros::spin-once)
Expand All @@ -16,7 +18,23 @@
(setq msg (instance jsk_robot_startup::Email :init))
(send msg :header :stamp (ros::time-now))
(send msg :subject subject)
(send msg :body body)
(send msg :body
(mapcar #'(lambda (e)
(cond ((derivedp e image-2d)
(if (> (length (send e :entity)) (* 8 8192))
(warning-message 3 "The size of img is too large (~A)~%You may encounter 'too long string' error, see https://github.com/euslisp/EusLisp/issues/2 for more info~%" (length (send e :entity))))
(instance jsk_robot_startup::EmailBody :init :type "img"
:img_data (base64encode (send e :entity))
:img_size 100))
((probe-file e)
(instance jsk_robot_startup::EmailBody :init :type "img" :file_path e :img_size 100))
((and (> (length e) 0) ;; check html
(eq (elt e 0) #\<)
(eq (elt e (1- (length e))) #\>))
(instance jsk_robot_startup::EmailBody :init :type "html" :message e))
(t
(instance jsk_robot_startup::EmailBody :init :type "text" :message (format nil "~A" e)))))
(if (atom body) (list body) body)))
(send msg :sender_address sender-address)
(send msg :receiver_address receiver-address)
(send msg :smtp_server smtp-server)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,36 @@
(ros::spin-once)
(setq receiver-address (ros::get-param "~receiver_address"))
(setq attached-files (ros::get-param "~attached_files" nil))
(unix::sleep 10) ;; wait for server
(while (or (null (ros::get-num-subscribers "email"))
(<= (ros::get-num-subscribers "email") 0))
(ros::ros-warn "wait for email topic")
(unix::sleep 1))

(ros::ros-info "Sending a mail to ~A" receiver-address)
(send-mail "test-mail" receiver-address "test" :attached-files attached-files)
(ros::ros-info "Sent a mail")
(send-mail "test text mail" receiver-address "test")
(ros::ros-info "Sent a text mail")
(unix:sleep 1)

(send-mail "test html mail" receiver-address "<h1>test with html mail</h1>")
(ros::ros-info "Sent a html mail")
(unix:sleep 1)

(send-mail "test attached mail" receiver-address "test with attached image" :attached-files attached-files)
(ros::ros-info "Sent a mail with attached files ~A" attached-files)
(unix:sleep 1)

(when attached-files
(send-mail "test image embedded mail (file)" receiver-address (append attached-files (list "test with embedded image")))
(ros::ros-info "sent a mail with embedded image ~a" attached-files)
(unix:sleep 1)
;; read png/jpeg file, but do not extract to raw image, keep original compressed data in (img . entity)
(setq img (read-image-file (elt attached-files 0)))
(setq (img . entity) (make-string (elt (unix:stat (elt attached-files 0)) 7))) ;; size of file
(with-open-file (f (elt attached-files 0)) (unix:uread (send f :infd) (img . entity)))
(send-mail "test image embedded mail (string)" receiver-address (list "test with embedded image" img))
(ros::ros-info "Sent a mail with embedded image ~A" img)
(unix:sleep 1)
)

(ros::roseus "shutdown")
(exit)
3 changes: 2 additions & 1 deletion jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
string type # text, html, img
string message # For text and html type
string file_path # For img type
string file_path # For img type, set file path
string img_data # For img type, you can also use base64 encoded image data instead of file path
uint8 img_size # For img type [percent]
41 changes: 24 additions & 17 deletions jsk_robot_common/jsk_robot_startup/scripts/email_topic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import socket
from socket import error as socket_error
import yaml
import copy
import random, string # for image cid
import base64


class EmailTopic(object):
Expand Down Expand Up @@ -44,7 +47,11 @@ def __init__(self):
'email', Email, self._cb, queue_size=1)

def _cb(self, msg):
rospy.loginfo('Received an msg: {}'.format(msg))
msg_compact = copy.deepcopy(msg)
for content in msg_compact.body:
if len(content.img_data) >= 64:
content.img_data = content.img_data[:64] + "...."
rospy.loginfo('Received an msg: {}'.format(msg_compact))
send_mail_args = {}
# Set default value for self._send_mail arguments
send_mail_args['subject'] = ''
Expand Down Expand Up @@ -83,27 +90,27 @@ def _send_mail(
elif content.type == 'html':
msg.attach(MIMEText(content.message, 'html'))
elif content.type == 'img':
if content.file_path == '':
rospy.logwarn('File name is empty. Skipped.')
if content.img_data != '':
embed_img = MIMEImage(base64.b64decode(content.img_data))
cid = ''.join(random.choice(string.ascii_lowercase) for i in range(16))
elif os.path.exists(content.file_path):
with open(content.file_path, 'rb') as img:
embed_img = MIMEImage(img.read())
cid = content.file_path
else:
rospy.logerror("'img' content requries either file_path {}".format(content.type))
rospy.logerror(" or img_data {} with img_format {}".format(content.img_data, content.img_format))
continue
if not os.path.exists(content.file_path):
rospy.logerr(
'File {} is not found.'.format(content.file_path))
return
with open(content.file_path, 'rb') as img:
embed_img = MIMEImage(img.read())
embed_img.add_header(
'Content-ID', '<{}>'.format(content.file_path))
embed_img.add_header(
'Content-Disposition', 'inline; filename="{}"'.format(
os.path.basename(content.file_path)))
msg.attach(embed_img) # This line is necessary to embed
embed_img.add_header(
'Content-ID', '<{}>'.format(cid))
embed_img.add_header(
'Content-Disposition', 'inline; filename="{}"'.format(os.path.basename(cid)))
msg.attach(embed_img) # This line is necessary to embed
if content.img_size:
image_size = content.img_size
else:
image_size = 100
text = '<img src="cid:{}" width={}%>'.format(
content.file_path, image_size)
text = '<img src="cid:{}" width={}%>'.format(cid, image_size)
bodytext = MIMEText(text, 'html')
msg.attach(bodytext)
else:
Expand Down

0 comments on commit 8d59a2e

Please sign in to comment.